D For A Web Developer

Adam D. Ruppe via Digitalmars-d digitalmars-d at puremagic.com
Tue Apr 29 21:12:58 PDT 2014


On Wednesday, 30 April 2014 at 03:20:16 UTC, Rikki Cattermole 
wrote:
> We should probably work together on this sort of stuff! As we 
> seem to have similar ideas

Yea, I wrote my version several years ago (IIRC 2009 or early 
2010) and since then D has grown as has my knowledge of it. I 
kinda want to write a web.d 2.0 that cleans everything up but eh 
I have a lot of things I want to do and web.d 1.0 works so no big 
rush.

The 1.0 has a lot of cool stuff though, like it can avoid JS 
calls by referencing the result of another function in the URL, 
all pretty transparently. So like if you wrote, in JS:

Foo.add(Foo.add(1,2), 3).get(alert), it should only result in one 
HTTP request. The proxy object when used as an argument just 
emits an indirect reference through magic URL params. Kinda cool, 
though it doesn't go as far as I'd like.


Among what I'd like to clean in web.d 2.0:

web.d supports what it calls "ApiObjects", which map to RESTful 
uris:

class Poo : ApiObject {
    this(ApiProvider parent, string identifier) {}
    auto GET() { }
    auto POST() {} // etc
    auto bar() {}
}

If you went to:

/Poo/cool-beans

it would call (new Poo(parent, "cool-beans")).GET(). Then 
/Poo/a/bar calls new Poo("a").bar and so on.

The problem is this is really reliant on things like the ending 
slash, and it issues redirects to force it to be there or not be 
there.

The implementation is also kinda buggy in general, it is supposed 
to beautifully nest, but it only kinda does. Getting an index of 
all things also doesn't work quite right, you have to write a 
separate method for that.

So I'd like to clean all that up and actually design it instead 
of growing on cool hacks as they come to mind.

Nested ApiProviders don't work exactly right either. They are 
supposed to do a chain of magic:

class Foo : ApiProvider { auto whatever() {} }
class Bar : ApiProvider {
    alias Foo foo;
}

Then, /foo/whatever does (new Foo((new Bar))).whatever. That part 
works. The things is each class can also provide a postProcess 
method to modify the document after it is generated. That's 
*supposed* hit everything, but sometimes it doesn't, I think it 
only works two levels deep right now, really hairy implementation.

The other problem is the Javascript generator doesn't really 
understand nesting. Ideally, nested ApiProviders are made 
available through dots and nested ApiObjects are workable through 
JS proxy objects.

This looks like what you managed to do so that's cool.


I also need to clean up the reflection generation to make it 
easier to use and make path info accessible outside just the 
automatic routing (or the low level Cgi.pathInfo which doesn't 
tell you where it starts!).

Reflection should be generated once upon startup then reused 
forever as an immutable object. Currently, reflection is 
partially regenerated on each request - eek.


I also wrote a _register*Processor family fairly recently (like 
December 2012) that kinda obviates the old postProcess and back 
in January this year, changed the session to put it all in 
cookies instead of files. That stuff is awesome, so much better 
than the old way. Should consider doing them from the ground up 
now!

(Also, ironically, I was a big pusher for UDAs for web.d... but I 
barely actually used them after they were made available. I 
really wanted to put them on parameters tho, otherwise convention 
over configuration is kinda how i play it LOLOL)



oh yeah and it could be documented somewhere other than my brain, 
the sloppy source, and random forum posts so ppl can know about 
it all. but meh.

All that said, it manages to get the job done for me so I'm not 
in a huge rush to actually fix any of it.


More information about the Digitalmars-d mailing list