D2 & Web-Framework

Adam D. Ruppe destructionator at gmail.com
Thu Jul 14 18:00:51 PDT 2011


Let me list some of the newer features in web.d too, added in
the last couple weeks.

class ApiObject;

These let you expose a more object oriented interface to your
stuff on the url.

====
class User : ApiObject {
   this(Foo foo, string id) {}
}

class Foo : ApiProvider {
   alias User user;
}
=====

Now, when the user goes to:

yoursite.com/yourapp/user/username

It instantiates one of those User classes, passing "username"
as the second argument to the constructor.

Then, you can add methods to your ApiObject and call them with
additional slashes on the url. Or, you can put in methods
with the name of an HTTP operation to apply straight to it.

string GET() { return "my name"; }

Now the url above works, running this GET() method. Or, you can
issue HTTP POST to it, and it runs POST() {}. Etc. The return
value is auto-formatted like with any other method.

You can also put in normal methods.

yoursite.com/yourapp/user/username/method

runs

new User(foo, "username").method();



This function is new and not fleshed out totally. The basics work,
but the javascript access isn't done yet - only top level procedures
are auto generated at this point. Basic reflection is working but
not even the sitemap uses it.

Eventually, I want to add proper support for static methods so
you can do things like get lists too, without requiring an
identifier.

That's another new method in the base class: sitemap. It lists
links to your functions. Nothing fancy, but soon I'll change
defaultPage to point to it, so creating a simple site is almost
fully automated.


Another new thing is you can now add aliases to other ApiProvider
children to your main one.

class Admin : ApiProvider { ... }

class Site : ApiProvider { alias Admin admin; }

Now, you can access the members of admin by going to
yoursite.com/yourapp/admin/methods...


This lets you separate out modules more easily. While they all
need to be aliased into the root apiprovider you provide, they
can be implemented in different modules.


It might be a good idea to make your own:

class YourApiProvider : ApiProvider {
 // override some of the methods here for a consistent site...
}

class Site : YourApiProvider {}
class Admin : YourApiProvider {}


Then you can easily have a centralized getDocument and postProcess
thing with normal overriding.


I'm considering automating that by making a chain of postProcess
calls based on where the aliases appear. Run the inner postprocess
first, then the outer one. I haven't decided yet.



You'll notice that I use alias a lot here. You don't strictly
have to, but I like to have the implementation easily separated,
which alias allows, and for the public name to not always match
the internal name (seen here with captialization). So that works
too with alias.


Another new thing is _initialize vs _initializePerCall, meant
to give more flexibility in a FastCGI situation. Using regular
CGI, it doesn't really matter since the process only handles one
call anyway.


I think that's everything recent.


Eventually I should write this documentation somewhere other
than the newsgroup!


More information about the Digitalmars-d mailing list