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!