A CRUDy Central Claim
In the REST world view, resources are primary. The role of HTTP is to perform one of four functions on resource concepts. These functions are POST, GET, PUT and DELETE. Described in order, POST implies the creation of new resource information, GET implies the reading of existing resource information, PUT implies the updating of existing resource information and DELETE implies the removal of resource information. If we look at these four HTTP request methods, we will find they map to the well-known verbs from the data storage domain: Create, Read, Update and Delete. REST advocates note that (and this is some extrapolation on the original REST model) these four verbs encompass all we might ever want to do with resources on the Web. If we add XML to HTTP as a payload and provide schema descriptions, we can fit a generalized cross-platform data format square inside of a proven, now nearly ancient technology such as HTTP. REST advocates proceed with an inductive sort of argument that builds upon the tremendous success of the Web. And here at last is where we really get to the core of the debate: Resources on the Web can have at least two representations, (a) a hypermedia or hypertext representation for humans, and (b) a machine-readable representation for solving "web services" or SOA types of problems. REST advocates look at the technology stack surrounding SOAP and SOA and chuckle a bit on the inside-we already have a proven, scalable technology (HTTP) that solves a nearly unbounded integration problem. If we can solve the unbounded version, this surely should apply as well to the bounded enterprise version of the problem. Why reinvent the wheel? The assertion of REST advocates is that the diversity of resources should be immense, but the number of verbs (Create, Read, Update, and Destroy) should be scarce. All that needs to be done can be done with CRUD, or so it is claimed. This does seem like a grand claim indeed: how can all enterprise business functions, both B2B and EAI be encapsulated in just four verbs? Indeed, the most common objection against REST is this perceived limitation. Before we examine this aspect of the debate further, however, we will examine a real-world example service that offers both REST and "traditional" SOAP interfaces to see how the messages manifest differently on the wire.
A Storage Service Example
The example that follows is adapted from a commercial web storage service, but the specifics have been changed to mask the actual service vendor. This example is central because this particular service offers both SOAP and REST type interfaces, which are prime candidates for looking at the similarities and differences between the approaches. The idea behind such a service is to allow web developers to store an arbitrary amount of data into keyed containers, which can then be used for retrieval at a later point in time. This particular service charges users of the service based on bandwidth of objects stored and retrieved from these logical containers. The service considers objects to consist of metadata and then an opaque object payload. The idea behind such a service is to provide a scalable, reliable, low-latency generic data store. You can think of this type of storage service as a building block for just about any distributed web application. Figure 3 summaries the basic concepts of container, key, and object.
In Figure 3, objects are stored into logical containers. The containers are named along with a key that allows the service to map from a combination of key and container name to the object itself. Further, objects also contain some metadata, which is in the form of media type information along with the octets that comprise the opaque payload. You should note that in this model, the containers can hold more than one key; in fact, one per object stored in each container. The operations allowed on these storage service artifacts are further defined as follows: (a) Container Creation, (b) Object Storage, (c) Object Retrieval (Non-Destructive), (d) Object Deletion, and (e) Key Listing. In addition to these basic operations, there are also other practical issues such as permissions (for others to read and write buckets) as well as authentication to the service itself. Other operations could also be added, but this represents a basic set for our purpose here.
So how do these operations map to real requests and responses in REST and SOAP? What do the messages on the wire look like? The first thing to remember is that with REST we are really only dealing with four fundamental operations applied to resources. This implies that REST messages come in the form of only GET, POST, PUT and DELETE whereas with SOAP, we can express the method itself within the request. Tables 2(a) and 2(b) shows the mapping between the abstract operation name, the equivalent REST operation and SOAP method. You should note that brackets in the following table (shown in bold) denote variables that would be filled in with actual values. Also, Table 2 just shows the request side of the messages for brevity.
You should note that Table 2 does not show complete requests, just the essence of each request. The REST requests are straight HTTP requests and the only thing omitted in the samples shown would be the HTTP headers. In this case, the headers would contain authorization information in the form of a keyed hash that identity and authenticity of the requester. Because the requests are stateless, this authorization information must be present in each request. Conversely, the SOAP requests shown are really only the SOAP body. While HTTP could also be used as the transport for SOAP, there is no guarantee that it will be, so any extra information such as authorization elements must be expressed as XML elements inside the SOAP request. Further, the SOAP example here leaves out any SOAP headers as well as any namespace declarations that appear in the body of the messages. Finally, the SOAP example also makes use of SOAP Attachments, specifically in the case where an object is stored at the service.
As you ponder the differences between each style of request, it should be obvious that the REST-based messages and model seems much simpler. It achieves the same basic functionality by riding on top of mechanisms already provided by HTTP. However, does this simplicity scale when the services become more complex? How would REST handle real world scenarios that go beyond a basic storage service? What about reliable messaging, transaction support, and asynchronous communication styles? How would message-level encryption and digital signatures be handled with REST? SOAP proponents may argue that the storage service works better as a REST architectural style simply because it is such a simple service and it already manifests itself as create, read, update and delete operations. REST proponents typically counter with observing that if we tied down the number of verbs, the diversity in nouns (or resources) will account for the additional complexity. REST proponents firmly believe that all problems in computing eventually fall into the CRUD domain, and all that must be done is the identification and definition of these resources. We argue that software complexity never really decreases, it just shifts around. Thus, if we use only four verbs, the diversity and complexity of the nouns must increase. This is typically done by REST proponents with careful examination of the domain and a liberal definition of what a noun can be. For example, if we were to model the relationship between users and groups with REST, we would not attempt to create nested nouns, where users fit inside groups and groups contain a set of users. Instead, we would create a set of singular relationships between each user and their group. Once we identify the noun as a relationship we can apply CRUD operations to it.
This design paradigm surely sounds elegant, and in fact it may be true. However, the time needed for this "discovery of nouns" may not be aligned with the needs of business.
Evaluating REST and SOAP
As mentioned in the previous section, SOAP proponents would look at REST architecture models and make claims that HTTP is designed well for a stateless web, but the REST architectural style doesn't account for all that is required in a full-fledged SOA. The central argument given can be characterized by pointing out additional requirements that only a SOAP framework can provide. Some of these requirements are listed as follows:
- Reliability: Many verticals, such as healthcare and financial services, have strong requirements for reliable transactions. In the case of healthcare these could be long-running transactions where state must be stored over a long period of time. While it is yet unproven, SOAP does have ongoing standardization efforts to provide reliable messaging between SOAP endpoints, complete with delivery assurances appropriate for different use cases. As we have seen, REST is fundamentally stateless and currently lacks this capability.
- Description: When messages are sent with REST, the de-facto standard is to make the payloads opaque or use POX (plain old XML). If we consider XML schema to be a type description language, REST does have a mechanism for describing payloads, but no service description language. REST proponents would argue that API descriptions are not applicable with REST because there are only four operations, but this ignores the standardization work that also includes policy information as part of SOA service descriptions. SOAP proponents would argue that service descriptions allow for richer types of messaging interactions to be universally understood and processed, rather than the standard request/response exchange pattern defined by REST.
- Message Level Security: REST can piggyback easily on top of point-to-point security protocols such as SSL or IP-Sec, but it has no mechanism for persistent security properties applied to the messages themselves. If we remain in the context of POX, one could make an argument that raw XML Security standards could be used to sign and encrypt payloads, but there is no standard for where to place identity tokens in REST style messages. SOAP, by contrast, has a proven message-level security mechanism in the form of OASIS WS-Security that has a proven track record of interoperability.
- Publish/Subscribe: Many business verticals rely on publish/subscribe type messaging coupled with message-level routing to publish information to a diverse number of endpoints over an application level network. The REST model doesn't directly apply to environments that use anything other than a request/response message exchange paradigm. SOAP, by contrast, has standardization efforts that allow for one-way messaging as well as topic based publish and subscribe standards. SOAP also has header mechanisms that allow portions of messages to be targeted at certain intermediary targets
As it stands, SOAP appears to be more closely-aligned with business vertical requirements and REST appears to be more closely-aligned with the nature of how the Web works. Truth be told, it would be cumbersome and weighty to use SOAP for something like the storage service if none of these additional SOAP features just described would ever be used. SOAP frameworks and the WS-* stack are often criticized for being myopic and ignoring the success of the Web. In reality, this stack of specifications is vendor designed and it is no mystery that it trades features for simplicity. The "Web" as such may have little to do with solving the bounded integration problem shown in Figure 1. In short, it is not the goal of WS-* to solve the unbounded integration problem, but merely provide business value for the here and now. As we segue into the next section, our discussion of the unbounded integration problem and REST will be taken up a level in terms of the Web 2.0 phenomenon. From this elevated viewpoint we look again at the relationship of SOAP and REST, but in the broader sense of SOA and Web 2.0.