one of the requested items was a higher-level interface built on top the current building blocks that would be easier to use. One of such abstractions would be an HTTP request router.
I usually do my research and check what others have done (not only in C++), read a lot of spec and do a design on my own (sometimes I ask for feedback of a few chosen ones). I rarely ask for public feedback because I usually can solve the interface issues on my own.
The "tree style" is the style where you declare some paths to be handled and each request will be routed to at most one handler. You'll find this style usually when the author advertise a ReST support library (e.g.crow[1]).
Tree is what vast majority of web frameworks do. Note that also Node.JS is "hip" today it does stuff in very unconventional way because it is JS and because it is deeply event driven (not always a good thing) Take a look what I do in CppCMS with URL mapping.
I thought I could combine and allow both styles. Actually, Boost.Http don't force you to use any style and both could be used.
I suggest do ONE thing but do it well.
Knowing this is Boost and Boost is about serious C++ users I know I must be concerned about performance. Therefore, many may not like the std::function<> approach. It can imply some hidden allocation that you pay even if the handler is not going to give up on the route.
Negligible - you should create routing + callbacks at the application start so it does not matter how much std::function allocates as long as you don't copy it on each request. Also note that in CppCMS I use a variant of function called "callback" that is reference counted and had much cheaper copy.
Another approach would be to turn the handlers into template functors. However, this would be too much burden on the user.
Please don't... Think about end users and compilation times.
Other APIs use a passive style and constantly check if there is network activity and schedule new socket reads. Boost.Asio is more explicit and Boost.Http follows along. An active style is useful because it'll allow you to defer new operations to later when your server is under heavy load. Anyway, I felt that maybe I'll need a "done" function and I've added an empty one for now. I'll see if I'll really need it later when I integrate everything together. For now, just know that the "done" function does nothing.
See... it is nice to have defer functionality for stuff like server-sent-events or another hip called web sockets. But vast majority of web api/web work need to do stuff synchronously...
Some points that I'll tackle LATER will be:
- A router is a handler too, then you can have nested routers.
It is actually must as usually you work as tree
- The router doesn't take the rule, only the handler. Later, I'll make algorithms that adapts rules and conditionally call your handler or pass the route to the next handler. This design is more flexible and I wish I could also use it in "tree style too".
I don't understand but sounds like bad idea - when you build routing tables it should be clear what path is mapped to what if you separate it in the code it would be messy ------------------------------ DISCLAIMER : I'm THE author of CppCMS [1] high performance C++ web framework I've been working on CppCMS for MANY years - and there still lots of work to do because web is virtually infinite field. Implementing fancy HTTP library that allows to map callbacks to URLs is about 1%-5% of actual stuff usable HTTP system needs. Basic HTTP libraries would always limit you because web is a huge field. I'd suggest take a look on any of existing C++ web frameworks that has a good user base and contribute to it as lots of work had already been done in very good way. And of course I mean - look at CppCMS that already solved huge amount of problems you are talking about. Artyom Beilis [1] http://cppcms.com/