2011-02-06

Howto design a webapp C++ MVC API?

So I decided to start on my webspeed-project doing a http/fastcgi server. So far I'm just implementing the http-server itself, but designing it so that a typedef will turn it into a fastcgi server instead.
The implementation is very simple, just create a doeplus::webapp::http_server, set the callback and then send content to the doeplus::webapp::connection provided in the callback.
It looks like this:

int new_connection(doeplus::webapp::connection::ptr connection){
std::string content("Send this to the browser 200 times. ");
for(int i(0);i!=200;++i){
connection->send_response(content,false);
}
connection->send_response(" Finished",true);
return 0;
}

int main(int argc, char *argv[]) {
boost::asio::io_service io_service;
doeplus::webapp::http_server myserver(io_service,"127.0.0.1",9010);
myserver.connection_callback() = &new_connection;
io_service.run();
return 0;
}

Pretty easy right. But it's not ready for production yet because I still have the major task in front of me. I will implement a MVC design for webapps.

How does a good MVC implementation looks like in C++?
Not an easy question. Lets see what we are trying to accomplish:

Classic webapps maps the address to the filesystem and associate file extension to something being executed. Instead of this approach I'd like to map the path to different controllers. Modern webapps are using addresses like this one: http://example.com/myapp/path/to/what/im/doing/dosomething
Breaking down the path we have one "root" path to the webapp "myapp". Next we have a path to something related to what we are doing, and last we have the path to the action we would like to take.
So with this design we can break down the path to different kind of controllers. First we have a WebappController "myapp". Next we have several PathControllers "path", "to", "what", "im", "doing". Finally we have a "Action" in the last "doing" controller called "dosomething".

I can see other kind of information that can be hidden in the path itself. Take this example:
We have a forum-webapp with a administration where the administrators can edit users information. The path to a page like that could look like this:
http://example.com/forum/admin/users/35/edit
Using a path like this we can easily go from the "edit" action to the "editpermission" action of the user without providing the users id (35) with a very easy link to "editpermission".
With this in mind, we probably need to provide a type of controller that can handle more dynamic paths - maybe a RegexpPathController.

So far we have 3 different controller types:
  • WebappController: This controller need to define the path to the webapp itself and maybe even on what virtual host to use. The path to the webapp itself should also be able to be just root "/".
  • PathController: This should be a subpath to another controller so that you can add the PathController to your WebappController or to another PathController.
  • RegexpPathController: Just like the PathController, but can also contain dynamic content.
  • There are probably other controllers to think of (like a ExtensionController), but this is what I can find out now.
The next thing is how a "action" will work. The first design that comes to mind is that a "action" is a method (function) in the controller, but there are alot more to think about.

What exactly will happen when a user of the webapp direct the browser to http://example.com/forum/admin/users/35/edit ???

This is the big question that I've been asking myself. What is the best design for this?
Lets assume that we somehow has build one hierarchy of the controllers and the actions when the webapp was started.
We could just find out in the controller-hierarchy what action to execute and provide necessary information to the action and execute it. Although this will assume that each action is threadsafe since several simultaneous calls can be made to the same action.
Another option is that we can find out the controller-hierarchy and create a copy of the controller-object to that path. This approach may be better since the controllers now can be used for user-specific information like a User-object and the controllers can contain helper-methods for authentications and stuff like that.
Maybe I should implement different kind of controllers depending on if I want a unique controller-object for each call or a "static" object for the whole server?

I'm not done yet, and I have several designquestions to make decisions about.
More to come... soon...

No comments:

Post a Comment