On Wednesday, 30 April 2014 at 04:12:59 UTC, Adam D. Ruppe wrote:
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.

It does look like web.d was a bit of a precursor to Cmsed (unintentionally) strangely enough. Although I definitely would like to hear more about asynchronous javascript instead of my synchronous based code and how I can combine it at some point.

Reply via email to