2016-04-24 18:34 GMT-03:00 Vinnie Falco
Could you please write an example of how do you imagine the ideal server-side API?
Well, being role-agnostic means the same functions are used by both clients and servers. The only meaningful difference is that a server will receive request objects and send response objects instead of the other way around. The message class template distinguishes requests and responses using a bool "isRequest" template argument. These statements each declare a response: [...]
This makes me think that the two projects are more alike than you might think. The main difference here is just that Boost.Http's Message don't carry request-exclusive members (HTTP verb, uri) or response-exclusive members (status code, status messages) and methods that work on them take them separately. I'm open to follow a design more similar to yours (just need to discuss with Bjorn and other members first as I remember this decision was taken to follow a more fundamental message-based model). Another main difference is that Boost.Http server side design is really concerned about different HTTP backends. However, this is only observed in details and I really doubt they'll bother you. At most, I need to implement more convenient functions to remove the amount of boilerplate needed today (already on the TODO list and on the GitHub issue tracker). I believe the rest of the differences are really minor. Of course I might be wrong and I'll know once more information about the project is exposed (documentation maybe). "Some reviewers also felt that HTTP/2 should be part of Boost.Http,
partly because that would demonstrate the extensibility of the current design, and partly because the library would be in a stronger position to attract users if it offers more than its competitors."
The IETF adopted as a goal for HTTP/2, to leave the message the same (while changing its wire format). Therefore, Beast.HTTP's message model is already HTTP/2-friendly.
As for the extensibility of the design, free functions to send and receive HTTP messages are fundamentally incompatible with HTTP/2, which requires ongoing state to decompress headers and multiplex streams. And yet, we know that free functions to send and receive HTTP/1 messages are useful and sorely needed.
Furthermore HTTP/2 adds features that don't make sense for HTTP/1. What would you do with the stream ID? It is not part of the message model, because it describes a transport level property (and what meaning would it have for a HTTP/1 message? or someone who is using the message object but not using any sockets at all?) What about the interface to inform the peer of a new receive window size? What about setting stream priorities/weights? How do we sort all this out?
The interface for HTTP/1 should consist of a universal message model, plus functions to send and receive those messages on sockets. The interface for HTTP/2 should be a class template that wraps a socket (similar in style to beast::websocket::stream), deals in the same universal message model, and offers member functions to send and receive those messages with associated stream IDs as well as adjust HTTP/2-specific session parameters.
We respectfully disagree with those reviewers who feel that a single interface should serve the needs of sending and receiving both HTTP/1 and HTTP/2 messages.
But the two interfaces could be very similar. We also don't need force the user to mess with stream IDs. Server push is another story and indeed needs new APIs. -- VinÃcius dos Santos Oliveira https://vinipsmaker.github.io/