Yesterday I was chatting with Matt after he reviewed the paper I plan to submit for the next Bill Gates Think Week and he pointed out something that had been nagging me about using REpresentational State Transfer(REST) as a model for building distributed applications.
In the current Wikipedia entry on REST, it states
An important concept in REST is the existence of resources (pieces of information), each of which can be referred to using a global identifier (a URL). In order to manipulate these resources, components of the network (clients and servers) communicate via a standardised interface (HTTP) and exchange representations of these resources (the actual files uploaded and downloaded) -- it is a matter of debate, however, whether the distinction between resources and their representations is too Platonic for practical use on the web, though it is popular in the RDF community. Any number of connectors (e.g., clients, servers, caches, tunnels, etc.) can mediate the request, but each does so without "seeing past" its own request (referred to as "layering", another constraint of REST and a common principle in many other parts of information and networking architecture). Thus an application can interact with a resource by knowing two things: the identifier of the resource, and the action required -- it does not need to know whether there are caches, proxies, gateways, firewalls, tunnels, or anything else between it and the server actually holding the information. The application does, however, need to understand the format of the information (representation) returned, which is typically an HTML or XML document of some kind, although it may be an image or any other content.
An important concept in REST is the existence of resources (pieces of information), each of which can be referred to using a global identifier (a URL). In order to manipulate these resources, components of the network (clients and servers) communicate via a standardised interface (HTTP) and exchange representations of these resources (the actual files uploaded and downloaded) -- it is a matter of debate, however, whether the distinction between resources and their representations is too Platonic for practical use on the web, though it is popular in the RDF community.
Any number of connectors (e.g., clients, servers, caches, tunnels, etc.) can mediate the request, but each does so without "seeing past" its own request (referred to as "layering", another constraint of REST and a common principle in many other parts of information and networking architecture). Thus an application can interact with a resource by knowing two things: the identifier of the resource, and the action required -- it does not need to know whether there are caches, proxies, gateways, firewalls, tunnels, or anything else between it and the server actually holding the information. The application does, however, need to understand the format of the information (representation) returned, which is typically an HTML or XML document of some kind, although it may be an image or any other content.
Compare the above to the typical notion of service orientation such as that espoused in the article A Guide to Developing and Running Connected Systems with Indigo by Don Box where he wrote
In Indigo, a service is simply a program that one interacts with via message exchanges. A set of deployed services is a system. Individual services are built to last—the availability and stability of a given service is critical. The aggregate system of services is built to allow for change—the system must adapt to the presence of new services that appear a long time after the original services and clients have been deployed, and these must not break functionality. Service-oriented development is based on the four fundamental tenets that follow: Boundaries are explicit A service-oriented application often consists of services that are spread over large geographical distances, multiple trust authorities, and distinct execution environments...Object-oriented programs tend to be deployed as a unit...Service-oriented development departs from object-orientation by assuming that atomic deployment of an application is the exception, not the rule. While individual services are almost always deployed atomically, the aggregate deployment state of the overall system/application rarely stands still. Services are autonomous Service-orientation mirrors the real world in that it does not assume the presence of an omniscient or omnipotent oracle that has awareness and control over all parts of a running system. Services share schema and contract, not class Object-oriented programming encourages developers to create new abstractions in the form of classes...Services do not deal in types or classes per se; rather, only with machine readable and verifiable descriptions of the legal "ins and outs" the service supports. The emphasis on machine verifiability and validation is important given the inherently distributed nature of how a service-oriented application is developed and deployed. Service compatibility is determined based on policy Object-oriented designs often confuse structural compatibility with semantic compatibility. Service-orientation deals with these two axes separately. Structural compatibility is based on contract and schema and can be validated (if not enforced) by machine-based techniques (such as packet-sniffing, validating firewalls). Semantic compatibility is based on explicit statements of capabilities and requirements in the form of policy.
In Indigo, a service is simply a program that one interacts with via message exchanges. A set of deployed services is a system. Individual services are built to last—the availability and stability of a given service is critical. The aggregate system of services is built to allow for change—the system must adapt to the presence of new services that appear a long time after the original services and clients have been deployed, and these must not break functionality.
Service-oriented development is based on the four fundamental tenets that follow:
Boundaries are explicit A service-oriented application often consists of services that are spread over large geographical distances, multiple trust authorities, and distinct execution environments...Object-oriented programs tend to be deployed as a unit...Service-oriented development departs from object-orientation by assuming that atomic deployment of an application is the exception, not the rule. While individual services are almost always deployed atomically, the aggregate deployment state of the overall system/application rarely stands still.
Services are autonomous Service-orientation mirrors the real world in that it does not assume the presence of an omniscient or omnipotent oracle that has awareness and control over all parts of a running system.
Services share schema and contract, not class Object-oriented programming encourages developers to create new abstractions in the form of classes...Services do not deal in types or classes per se; rather, only with machine readable and verifiable descriptions of the legal "ins and outs" the service supports. The emphasis on machine verifiability and validation is important given the inherently distributed nature of how a service-oriented application is developed and deployed.
Service compatibility is determined based on policy Object-oriented designs often confuse structural compatibility with semantic compatibility. Service-orientation deals with these two axes separately. Structural compatibility is based on contract and schema and can be validated (if not enforced) by machine-based techniques (such as packet-sniffing, validating firewalls). Semantic compatibility is based on explicit statements of capabilities and requirements in the form of policy.
The key thing to note here is that REST is all about performing a limited set of operations on an object (i.e. a resource) while SOA is all about making requests where objects are input and/or output.
To see what this difference means in practice, I again refer to the Wikipedia entry on REST which has the following example
A REST web application requires a different design approach than an RPC application. In RPC, the emphasis is on the diversity of protocol operations, or verbs; for example, an RPC application might define operations such as the following: getUser() addUser() removeUser() updateUser() getLocation() addLocation() removeLocation() updateLocation() listUsers() listLocations() findLocation() findUser() With REST, on the other hand, the emphasis is on the diversity of resources, or nouns; for example, a REST application might define the following two resource types User {} Location {} Each resource would have its own location, such as http://www.example.org/locations/us/ny/new_york_city.xml. Clients work with those resources through the standard HTTP operations, such as GET to download a copy of the resource, PUT to upload a changed copy, or DELETE to remove all representations of that resource. Note how each object has its own URL and can easily be cached, copied, and bookmarked. POST is generally used for actions with side-effects, such as placing a purchase order, or adding some data to a collection.
A REST web application requires a different design approach than an RPC application. In RPC, the emphasis is on the diversity of protocol operations, or verbs; for example, an RPC application might define operations such as the following:
getUser() addUser() removeUser() updateUser() getLocation() addLocation() removeLocation() updateLocation() listUsers() listLocations() findLocation() findUser()
With REST, on the other hand, the emphasis is on the diversity of resources, or nouns; for example, a REST application might define the following two resource types
User {} Location {}
Each resource would have its own location, such as http://www.example.org/locations/us/ny/new_york_city.xml. Clients work with those resources through the standard HTTP operations, such as GET to download a copy of the resource, PUT to upload a changed copy, or DELETE to remove all representations of that resource. Note how each object has its own URL and can easily be cached, copied, and bookmarked. POST is generally used for actions with side-effects, such as placing a purchase order, or adding some data to a collection.
The problem is that although it is easy to model resources as services as shown in the example in many cases it is quite difficult to model a service as a resource. For example, a service that validates a credit card number can be modeled as a validateCreditCardNumber(string cardNumber) service. On the other hand it is unintuitive how one would model the service as a resource. For this reason I prefer to think about distributed applications in terms of services as opposed to resources.
validateCreditCardNumber(string cardNumber)
This doesn't mean I don't think there is value in several aspects of REST. However I don't think it is the right model when thinking about building distributed applications.