July 2009
Volume 24 Number 07
Service Station - More On REST
By Jon Flanders | July 2009
Contents
Which is better, REST or SOAP?
What about security? Isn't SOAP more secure than REST?
What about transactions?
What about interoperability? Isn't SOAP supposed to be about interoperability? Isn't SOAP more interoperable than REST?
But what about metadata? So what if REST is so interoperable—there's no WSDL with REST, and without WSDL, I can't generate a client-side proxy to call a service. REST is hard to use.
What if I want to use a transport other than HTTP?
After all that information, aren't you telling me that REST is good for Internet-facing applications, and SOAP for enterprise applications?
Bottom Line
In the last two columns, I've described the basics of REST and talked about exposing and consuming Web feeds. In this column, I'll answer a number of questions that often come up when I make presentations or conduct training sessions on using REST to build service-based applications.
Which is better, REST or SOAP?
This is one of the most common questions I get about REST, and it is probably the least fair. Both REST and SOAP are often termed "Web services," and one is often used in place of the other, but they are totally different approaches. REST is an architectural style for building client-server applications. SOAP is a protocol specification for exchanging data between two endpoints.
Comparing REST with the remote procedure call (RPC) style of building client-server applications would be more accurate. RPC is a style (rather than a protocol, which is what SOAP is) of building client-server applications in which a proxy (generally generated from metadata) is used in the client's address space to communicate with the server and the proxy's interface mimics the server's interface. Although SOAP doesn't require the RPC style, most modern SOAP toolkits are geared toward (at least they default to) using RPC.
In contrast to RPC, REST lacks the metadata-generated proxy (see the next question for more information), which means that the client is less coupled to the service. Also, because REST relies on the semantics of HTTP, requests for data (GET requests) can be cached. RPC systems generally have no such infrastructure (and even when performing RPC using SOAP over HTTP, SOAP responses can't be cached because SOAP uses the HTTP POST verb, which is considered unsafe). SOAP intentionally eschews HTTP, specifically to allow SOAP to work over other protocols, so it's actually a little disingenuous to call SOAP-based services Web services.
My perspective is that both REST and SOAP can be used to implement similar functionality, but in general SOAP should be used when a particular feature of SOAP is needed, and the advantages of REST make it generally the best option otherwise.
What about security? Isn't SOAP more secure than REST?
This question touches one of my pet peeves because the answer is clearly no. It is just as easy to make a RESTful service secure as it is to make a SOAP-based service secure. In the majority of cases involving either REST or SOAP, the security system is the same: some form of HTTP-based authentication plus Secure Sockets Layer (SSL). Although technically the technology for secure conversations over HTTP is now called Transport Layer Security (TLS), SSL is still the name most commonly used.
What is true is that a SOAP-based service, because of the extra protocols specified in the various WS-* specifications, does support end-to-end message security. This means that if you pass SOAP messages from endpoint to endpoint to endpoint, over the same or different protocols, the message is secure. If your application needs this particular feature, SOAP plus WS-* is definitely the way to go. REST probably wouldn't be an option here because of its dependence on HTTP, and inherently you'd be designing a multiprotocol application. I believe that the fact that SOAP with WS-* enables end-to-end message-level security is the source of the misconception that SOAP-based services are more secure than RESTful services.
Another area in which the WS-* folks have spent a lot of time and effort recently is federated security. The simple idea behind federated identity is to create trust between two companies, where authenticated users from one company can be trusted and considered authenticated by another company without the second company having to maintain the authentication information (username and password, typically). The various WS-* specifications have implementations from all the major vendors, and Microsoft is integrating the ideas into Active Directory through Active Directory Federation Services (ADFS).
In the realm of federated security, the WS-* arena certainly has more standards than the RESTful arena (and this will probably always continue to be the case), but there are efforts to support federated security in the world of REST. OpenID is one such effort. The .NET Service Bus (part of Microsoft Azure) also contains a federated identity service, which works just as well with HTTP (and therefore REST) as it does with SOAP-based services.
What about transactions?
Here is another area in which SOAP and WS-* have explicit support for an "advanced" feature and REST has none. WS-Atomic Transactions supports distributed, two-phase commit transactional semantics over SOAP-based services. REST has no support for distributed transactions.
Generally speaking, if you want something like transactions in a RESTful system, you create a new resource. (Creating a new resource whenever you run into a problem with a RESTful system generally solves most problems.) You can have a resource called Transaction. When your client needs to do something transactional (such as transferring money between two bank accounts), the client creates a Transaction resource that specifies all the correct resources affected (in my example, the two bank accounts) by doing a POST to the Transaction factory URI. The client can then perform updates by sending a PUT to the transaction URI and close the transaction by sending a DELETE to the URI.
This, of course, requires some amount of hand-coding and explicit control over your system, whereas the WS-Atomic Transactions system is more automatic because (in the case of Windows Communication Foundation) it is tied to your runtime's plumbing.
If your system absolutely needs atomic transactional semantics across diverse systems, WS-Atomic Transactions is probably the way to go. Using distributed transactions in this way may or may not be smart because it increases the coupling between the two systems and creates potential problems if you aren't controlling the code on both ends. But the most important thing is to use the right tool for the right job (once you've figure out what the right job is).
In defense of REST, I think it is fair to say that given today's distributed, service-oriented architectures, coupling two endpoints so tightly using a distributed transaction may not be the best design. On the other hand, some situations call for this type of functionality, and if you need it, use SOAP and WS-Atomic Transactions.
What about interoperability? Isn't SOAP supposed to be about interoperability? Isn't SOAP more interoperable than REST?
If you define interoperability as the technical ability to communicate between two divergent endpoints, I assert that REST wins the interoperability battle hands down.
Since one of the driving points behind creating the SOAP specification was to create an interoperable way to communicate between different platforms and different languages, many people are surprised by this assertion. But a funny thing happened on the way to widespread interoperability: the WS-* specifications (and vendors' implementations of said specifications) made SOAP services less interoperable rather than more interoperable.
The problem in the SOAP and WS-* arena is the large number of different standards (and versions of each of those standards) to choose from. And when a particular vendor chooses to implement a particular standard, that vendor often provides an implementation that is just slightly different from another vendor's (or all others). This leads to problems whenever you have to cross vendor boundaries (languages and operating system).
Of course, even to use SOAP you need a SOAP toolkit on your platform, which most (but not all) platforms have today. And then you have to deal with myriad WS-* specifications and figure out which to use (or not to use) and how that affects interoperability. To be honest, it's kind of a mess out there.
In terms of platforms, REST has the advantage because all you need to use REST is an HTTP stack (either on the client or the server). Since almost every platform and device has that today, I would argue that REST has the widest interoperability. Given that mobile devices, household devices, POS devices, DVD players, and TVs all have Internet connectivity, there are more and more platforms for which having a full SOAP toolkit is impossible or unlikely. And even if you do have a SOAP toolkit for a particular platform, the chance of it working with another platform's implementation is not 100%.
But what about metadata? So what if REST is so interoperable—there's no WSDL with REST, and without WSDL, I can't generate a client-side proxy to call a service. REST is hard to use.
It's true that in the world of REST, there is no direct support for generating a client from server-side-generated metadata, as there is in the world of SOAP with Web Service Description Language (WSDL). A couple of efforts are being made to get such support into REST, one being a parallel specification, known as WADL (Web Application Description Language). The other is a push to use WSDL 2.0 to describe RESTful endpoints. I often say that REST is simple, but simple doesn't always mean easy. SOAP is easy (because of WSDL), but easy doesn't always mean simple.
Yes, using WSDL makes generating a proxy for a SOAP-based service easier than writing the code to call a RESTful service. But once you generate that proxy, you still have to learn the API. Nothing in the WSDL tells you which method to call first or second or whether you need to call the methods in any particular order at all. These are all things you need to figure out after you generate the proxy and are prototyping the code to use the service.
Building a client against a RESTful service means you are learning the service and how it works as you build the client. Once you have finished, you have a complete understanding of the service, its resources, and the interaction you can have with those resources. To me, this is a big benefit. Since RESTful services follow the constraints of REST (at least they are supposed to), there is a convention that you can easily follow as you determine the different parts of the service.
Also, out in the wilds of developer-land, most services are wrapped in something often called a "service agent," which is another layer of indirection to protect clients from changes in the service layer. This may be needed in either REST or SOAP.
Another point is that metadata-generated proxies are part of what SOAP was meant to get away from in the RPC era, namely local-remote transparency. The concept of having an API on the client that matches the API on the server was considered to be a bad idea, but that's exactly what happens in most SOAP-based services. Having a metadata-generated proxy in REST also reduces the chances of taking advantage of hyperlinking. Using hypertext as the engine of application state (HATEOAS) is one of the constraints of REST, and using it requires a more loosely coupled client API.
The last point I'll make is that as support for REST becomes more ubiquitous, building clients will get easier and easier. If you look at the Windows Communication Foundation (WCF) REST starter kit, it includes facilities that head in this direction. The new HttpClient API makes using HTTP much easier than using the .NET WebRequest/WebResponse API. Also, there is a new Paste as XML Serializable tool, which allows you to copy a piece of XML (say from the documentation of a RESTful endpoint) and generate a .NET type that can represent that XML instance in your application. This is similar to what the WCF tools do automatically for the whole service with WSDL. Over time, these tools will become much more sophisticated, further simplifying the client experience in WCF when using RESTful services.
What if I want to use a transport other than HTTP?
The common (somewhat sarcastic) answer from the REST community here is, "Go ahead, there isn't anything stopping you." Realistically, however, REST is currently tied to HTTP, if only because most developers and teams of developers do not have the time for the engineering effort necessary to get the semantics of REST to work over, say, TCP/IP.
The common answer is technically correct, because nothing is stopping you from implementing the concepts of REST over other protocols, but until vendors add support for this, I find it a dubious proposition for most.
After all that information, aren't you telling me that REST is good for Internet-facing applications, and SOAP for enterprise applications?
If you've read the rest of this column, you can probably imagine that I think this statement is generalized and false. Often I hear this sentiment after discussing the lack of explicit distributed transaction support in REST versus the explicit support in WS-Atomic Transactions. My retort is generally something like "Well, ASP.NET doesn't have support for distributed transactions, but does that mean ASP.NET isn't useful for enterprises?"
My point is that not every technology solves every problem, and there are plenty of technologies that don't support the typical features people think of when they think of enterprises but that are incredibly helpful for enterprises nonetheless.
In fact, when I think of enterprise applications, I often think of speed and scalability—scalability being one of the main differences between REST and SOAP. SOAP services are much harder to scale than RESTful services, which is, of course, one of the reasons that REST is often chosen as the architecture for services that are exposed via the Internet (like Facebook, MySpace, Twitter, and so on).
Inside enterprises, applications also often need to scale as well. Using REST means that you can take advantage of HTTP caching and other features, like Conditional GET, that aid in scaling services. Many of these techniques can't be used with SOAP because SOAP uses POST only over HTTP.
Bottom Line
I hope that after you read this column, you'll think that the answer to "Which is better, REST or SOAP?" is "It depends." Both the REST architectural style and SOAP and the WS-* protocols have advantages and disadvantages when it comes to building services. Those of us in the RESTafarian camp (yes, I must give full disclosure here: I am definitely in that camp) believe that for most service situations, REST provides more benefits than SOAP or WS-*. On the other hand, SOAP and WS-* have some features that are easy (and possible) to implement using REST. When you need those specific features, you definitely want to use runtimes and toolkits that can provide those features. Although this column wasn't specifically about WCF, one nice feature of adopting WCF is that it supports both REST and SOAP/WS-*. Moving back and forth between the two worlds becomes easier if you have one programming and runtime model to learn.
Send your questions and comments to sstation@microsoft.com.
Jon Flanders is an independent consultant, speaker, and trainer for Pluralsight. He specializes in BizTalk Server, Windows Workflow Foundation, and Windows Communication Foundation.