Question: what do you call two or more architects in a room? Answer: an argument. Now that Service-Oriented Architecture (SOA) is the topic du jour within many such rooms in enterprises today, one favorite argument is over Representational State Transfer (REST) and its relationship to Web Services. Many such discussions degenerate into a religious discussion over which approach is better, but as with most arguments in the SOA space, the reality is far more subtle. Up until now, ZapThink has been happy to stay on the sidelines of this battle, but the time has come for us to weigh in with the ZapThink take on the REST vs. Web Services debate.
The Context for REST and Web Services
This perennial debate centers on a core challenge of SOA: what is the best way to create a loosely-coupled Service interface? One approach is the style of distributed computing known as REST. REST depends on the Hypertext Transfer Protocol (HTTP) as a stateless client/server protocol for exchanging information in a request-response manner utilizing a simple set of well-defined operations: POST, GET, PUT, and DELETE. In REST, a resource is exposed using a Uniform Resource Identifier (URI), which often looks like a Uniform Resource Locator (URL) familiar from the Web. The idea with REST is to change some state of a resource, rather than calling some procedure on a remote system, as traditional Remote Procedure Call (RPC) methods of distributed computing mandate.
To illustrate this point, REST might call for a resource type Customer which might have hundreds of exposed URIs. For example, http://mysite/customers/insurance/rschmelzer might refer to my customer record in an insurance application. To modify information in that record, the user would POST or PUT an XML file into that URI and then GET that information back in a subsequent call to the URI. The key is that REST uses “nouns”, not “verbs”. Instead of making a call to a function called getcustomer and passing it a customerID, REST indicates that users make a call to a resource called customerID and throw some XML at it.
From a REST perspective, we don’t really care about the architecture of the underlying solution. We can leverage REST for n-tier applications or client/server solutions, just as easily as Service-oriented approaches. Indeed, any application can be “RESTful” if it exposes capabilities through a GET request via HTTP. While REST certainly aims for simplicity in distributed computing, its primary challenges are identifying and locating individual resources and building asynchronous, event-driven styles of interaction. The lack of standards for REST other than HTTP and XML also presents a challenge for both vendors and IT shops. In addition, we are still left to grapple with issues of semantics — that is, what exactly goes into that XML that is exchanged between clients and servers?
In SOA, however, a Service does not necessarily map to a resource, but rather to a set of operations or a composite business process. Indeed, a Service maps more closely to the concepts of capabilities and processes more so than the resources that those capabilities and processes act upon. In this regard, a Service may be exposed as a resource, and a resource might expose a Service, but there’s no a priori equivalence between Services and resources.
RPC vs. Document-Style Interactions
The real contrast, therefore, is not REST vs. SOA, but rather the conflict between REST styles of Service implementation and Web Services styles that have an operation-specific perspective. Keep in mind that Web Services don’t represent an architectural approach, but rather a set of standards for how we define Services (WSDL), communicate with Services (SOAP), discover their availability (UDDI), and perform other value-added security, reliability, composition, and management tasks. Services are abstractions to code, and thus don’t represent instantiations of code. That is to say, you can’t run a Service. You can only expose Service interfaces to underlying code that may or may not be Service-oriented. Since Services can’t run, the only thing we can focus on are the metadata-based interfaces and policies that govern the definition, interaction, and management of Services and their composition into business processes.
Services don’t focus on resources, but rather on operations. A Service might have many operations, dozens or hundreds, in fact. Each operation specifies a particular behavior for how the Service will handle incoming XML documents and produce corresponding results. However, at this point we’re posed with a challenge. Do we define a single WSDL document that specifies a Customer Service, with multiple operations for creating, modifying, and deleting records, or do we create multiple Services, each purpose-built for a specific operation, but accepting different XML documents to handle different use cases?
This question gets to the heart of the matter in discussing the difference between RPC-style and document-style approaches to Web Services. In the RPC style, Services are treated as if they were objects with methods, requiring a SOAP call to address a specific operation with a specific method call to evoke a response. The XML message in this instance looks like a call to a method, with parameters and functions. For example, we might call the getCustomerName operation on the Customer Service and pass an XML document that looks like <getName><id type=’integer’>1234</id></getName>. Thus, the RPC style requires that Service consumers know not only the specific operation they wish to call, but also its method and type. As a result, RPC is a tightly-coupled approach in which any change to the operation or method requires significant change to the Service consumers.
The REST approach contrasts starkly with RPC, where an object called Customer would have a multitude of operations for creating, deleting, and modifying records, with multiple, discrete instances of objects each referring to a different customer. Fundamentally, therefore, REST is more like the document style, which also contrasts with the RPC style by requiring only that Service consumers know the operations they wish to call. In the document style approach, we simply call the Service we want and pass it an XML document that the Service can process any way it wants. So, we might call the CustomerInfo Service and pass it an XML document that it is contracted to accept. In turn, the Service consumer would receive an XML document that it is expecting, as per the contract, with no reason to call any methods or specify any data types.
As a result, the document style offers a greater degree of loose coupling than the RPC style, since any changes to the methods or operations might have very little impact on Service consumers. In addition, the XML body of a document-style Web Services interaction contains the actual business message — the valuable stuff. Whereas in the RPC approach, the XML typically just describes the methods and parameters of the method call.
The fundamental difference, therefore, between REST and document-style Web Services is how the Service consumer knows what to expect out of the Service. Web Services have contracts, defined in WSDL. Since Web Services focus on the Service, rather than on the resource, the consumer has clear visibility into the behavior of the various operations of the Service, whereas in REST’s resource-oriented perspective, we have visibility into the resources, but the behavior is implicit, since there is no contract that governs the behavior of each URI-identified resource.
In REST, you are requesting a change to a state for a particular resource, but you aren’t specifying the operation. Indeed, in REST, the operations are all the same: GET, PUT, POST, and DELETE. But what these operations will actually do (some call this the “application protocol”) differs on a per-resource basis. If you have a resource-oriented view with the perspective that REST is an architectural style (as many do), then RESTful Services are exposed as a type of resource with constraints to ensure loose coupling and composability. If you take a Service-oriented perspective on enterprise architecture, however, then REST represents an implementation style for exposing Services that has as much validity as the document style of Web Service interactions.
The ZapThink Take
ZapThink champions Service Orientation as an approach to addressing the needs of the business with collections of Services that represent complex and changing business processes that in turn compose other Services. As a result, how to implement those Services is an implementation decision that can leverage a variety of technological approaches including REST or document-style Web Services. In other words, the debate over REST vs. Web Services is moot, as the question boils down to which is the right tool for the job.
The real challenge to applying REST as a means to implement loosely-coupled Services is that REST has no explicit contract to define behavior, which means that all behaviors are implied. In REST, the data pumped through a GET, PUT, or POST operation contain all the semantics necessary to understand how a Service behaves. Therefore, REST isn’t appropriate for organizations that wish to take a contract-first development approach aimed at maximizing reuse and composition, in addition to loose coupling. And that’s the rub with REST — SOA aims to reuse not just the resource, but also the operation and the composition as well.
In many ways, however, the debate about Web Services and REST is as pointless as arguing whether a hammer or a screwdriver is a better tool. While each of the approaches add specific value to exposing Services and resources, SOA is an overarching approach for dealing with ongoing change in a business environment. The business doesn’t care about the resources or even the Services themselves, but rather the business value that result from interacting with those resources and Services. It’s up to the architect to understand when to apply different architectural and implementation styles to best address their organization’s ongoing business challenges.