HTTP is not a transport protocol, HTTP is not RPC

Preamble: The intent of this post is to educate on how HTTP was designed to be used , clarify misconceptions and to give folks food for thought on different ways they can design a system. It is not to ignite a war against RPC. There are tradeoffs to consider when your design your system. If you are not designing a system that is to be consumed by many clients over a long time and where the server needs to evolve independently of the client, then using HTTP for RPC may be absolutely fine.

Recently there was a question on the forums asking why we encourage usage of HttpRequestMessage<T> / HttpResponseMessage<T> in the signature of a web api implementation. The point made in the post is that if you have an ICalculator contract which your API implements, then it’s violating SOC / inappropriate to have those messages as params and in the contract. The argument is valid when looking at HTTP from the standpoint of an RPC mechanism, which is actually a quite common view.

Not of the HTTP authors though. If you read Roy Fielding’s dissertation you will see very clearly that:

HTTP is not a transport protocol and HTTP is not RPC.

You might be surprised, but it is true. There are real quantifiable reasons for this that underlie the foundations of how and why the web infrastructure was built. Roy explains it much better than I can, though I still continually attempt to do it :-) I recommend reading what Roy has to say on the subject here in sections 6.5.2 and 6.5.3.

Back to our HTTP messages. This has deep implications in your API design. Once you accept that the thing that you are exposing is an HTTP resource which clients interact with via the uniform interface and not a class with standard OOP methods, you design them differently. Your APIs become a gateway where HTTP concerns are addressed and then work is delegated off to the business domain rather than being part of the business domain. Once they do, you can safely use HttpRequestMessage<T> and HttpResponseMessage<T> without fear as they are specifically for addressing HTTP concerns.

Mike Amundsen has a really nice post where he emphasizes this last point and why it is just better for us to embrace HTTP in our code and stop fighting it:

“the better way to deal with HTTP is to embrace it. let HTTP lead system designers in the direction of lossy, chunky, state-less designs. accept HTTP as the stable rarely-changing foundation for your implementations. learn to ‘think’ and ‘speak’ HTTP so that all your dist-net designs reflect the power, stability, and reliability of HTTP itself. and don’t fuss with it.”

You can read more about the design implications from a Web API perspective in my reply on the thread.

Interested in your thoughts.

This entry was posted in HTTP, REST. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://twitter.com/aliostad Ali

    This in fact is the fallacy that lead to the demise of WCF. By abstracting only the payload, all the transport context is lost. In fact, in the earlier versions of WCF, it was impossible to get even the IP address of the client connecting via TCP or HTTP.

  • Andrew Webb

    “make it malleable enough that you can [...] create more opinionated frameworks on top”  — hmmm, that is a good idea!  I like that a lot.  Do you think that Microsoft might do something like that?

  • http://blogs.msdn.com/gblock Glenn Block

    Well we deliberately decided not to make it opinionated about REST. There’ s a lot of varying (but valid) opinions on how to build a RESTful system. With web api we our goal has been to make it malleable enough that you can layer your own opinions / create more opinionated frameworks on top.

  • Andrew Webb

    Maybe the WCF Web API could/should be more constrained, rather than being “HTTP your way”.  Something like: “HTTP Roy’s way”.  Or… something I’ve been thinking about: a hyper-opinionated, severly constrained REST service + client framework, based on Node.

  • http://blogs.msdn.com/gblock Glenn Block

    Rick, the fact that you can achieve RPC over HTTP is besides the point from what it was designed for. I am not saying you can’t do RPC, or that the REST police will come after you.

     The point of this post is to clarify what HTTP was designed for. And that it is perfectly reasonable to not abstract away HTTP concerns and to deal with them head on in the code as our messages allow you to do.

    As to RPC, yes you can use HTTP  in ways other than that purpose, that is a trade off you can make. SOAP services do that in order to support tooling, integration, etc. As long as you make it consciously and understand the implications in your system, go for it. Many people that do it today don’t think about the implications, they do it because it’s easy. For some systems which are small, or using HTTP as an implementation detail, may not matter, though it could also bite you in the long run. 

  • http://twitter.com/rickggaribay Rick G. Garibay

    I agree with the concepts here, but asserting that HTTP is not a transport protocol is much too broad of a statement. There are tons of RPC architects and developers out there that use HTTP as merely a high reach, low friction protocol. Perhaps they are missing out on the beauty of HTTP as a transfer protocol, but we shouldn’t discredit that approach (not saying that you are) which is in production in thousands of enterprise systems and continues to be a valid approach, particularly in the enterprise.

    Not RPC is also too far reaching. It is entirely possible to implement a very generic SOAP contract that accepts any message and can be routed and dispatched to handlers accordingly, in fact we built an ESB who’s greatest strength is just that. This is still RPC, just more relaxed.

    That said, I agree with Glenn that when you change your mindset and use HTTP as _the_ interface, and factor your code into service agents/gateways that isolate your business logic from communication details, the friction is greatly reduced.

    But I don’t think this is not so much because HTTP is not a transport protocol as it is because the interface/contract is significantly more relaxed than traditional contract-first service implementations and really is no different than using TCP or pipes and deciding to stream bytes using a universally compatible binary encoder/decoder (ouch!).

    Either way, at some point in the stack, XML schema and OO contracts matter, it’s just a matter of where and when you want to deal with them.

    A common pattern I’m seeing these days  is to expose (typless) HTTP/REST heads which simply allows super simple on-ramping on the the fabric.  The extent to which careful factoring is applied to resources and RESTfullness varies, but the end result is that dealing with the (necessary constraints) of schema and type is simply pushed further behind the service boundary which in turn reduces friction as long as the API is well undersood.

    This is not at all to trivialize the enormous agility and advantages a resource (noun) approach can have over an RPC/operation (verb) in many situations, but  at the end of the day, we still live in a RPC _and_ resource world and both are appropriate for different situations so providign tools that allow us to strike the right balance is really key to achieving harmony in modern system design.

  • http://twitter.com/rickggaribay Rick G. Garibay

    I agree

  • Anonymous

    HTTP in a payload format with meaning attached to different kinds of messages. When explaining to SOAP/RPC folks, I found that explaining it as a payload format is easier than explaining it as an application protocol. 

  • http://twitter.com/woodjoe Joeyw

    Right, too few APIs expose this level of control properly.
    HTTP is more than a transport because it can describe the semantics of state synchronization.  This makes architecting for SOC more interesting because now business functions need to communicate the properties of the state of their output.  This is something that an in-process, same thread function call would never have to do.

    It would be good to have support for state expiration, caching etc. in a technology independent way. 

  • http://blogs.msdn.com/gblock Glenn Block

    @ChakravarthyDSK, good question.

    It is a TRANSFER protocol. It is designed to transfer resource state between clients and servers. I use servers plural because those servers might be intermediaries. When I issue a request, it might not be the origin server that responds, it might be cache/proxy server.

  • Anonymous

    A quick question.. Yes, I agree with you that HTTP is NOT a TRANSPORT PROTOCAL and NOT a RPC.. but if you have to define it what would you say?