Bindings, Platforms, and Innovation
This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.
Tracking change and innovation in the enterprise software development community

Posted by Subbu Allamaraju on Dec 16, 2008 03:57 AM
Roy Fielding recently remarked thatA REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace.
A statement such as this can be hard to grapple with. If servers control their own namespace without a fixed resource hierarchy, how do clients, and more importantly client developers, get to learn or discover URIs of resources? After all, for a long time, one of the fundamental assumptions of distributed client server development is that, in order to build, maintain and administer such an application, we need a formal description of the interface to the application a priori. Roy Fielding's statement seems to contradict this assumption.
Comprehensive Threat Protection for REST, SOA, and Web 2.0 Applications
The Role of Open Source in Data Integration
Intel® SOA Expressway Performance Comparison to IBM® DataPower XI50
Discussions about descriptions of RESTful systems is not new. Almost always, such discussions conclude with ideas like the above. See, e.g, the note on Debate: Does REST Need a Description Language? at infoQ last year that summarizes some of the discussions that took place then. The state of affairs is not very different today.
Despite a number of opinions expressed both for and against a formal description language for RESTful applications, description languages like WADL have gained some limited ground. However, since there is not a "standard" language that a machine could interpret, the most common route that server applications take is to document all URIs, HTTP methods supported, and structures of representations (e.g. as XML and JSON) so that client application developers can rely on such documentation to write code.
This approach, however, contradicts some of the fundamental principles of REST, as paraphrased by Roy Fielding above. Even if we ignore this objection, for those attempting to build distributed applications over HTTP RESTfully, the fundamental question remains. How can a server get away without formally defining a contract? Without a contract, how can we make sure that clients and servers are implemented correctly, not only to respective design specifications, but to other business/technical policies in place?
Distributed applications using HTTP as an application protocol, and built RESTfully, do have a contract, but of a different nature and kind. We need to know what to look for and where. Along the same lines, if we were to come up with a description language, it can not be similar to WSDL or WADL. My goal in this article is to answer the following questions.
Let me begin with an example.
The task is to write a client application that can transfer some amount from one bank account to another account of the same customer in a different bank.
Let me first describe all the interactions between the client and the server, and then look at a possible description of the contract.
Step 0: A user logs into the client. In order to keep this discussion focused, let me ignore all security aspects.
Step 1: The client uses a URI http://bank.org/accounts?findby=7t676323a to search for two accounts using the customer ID. Here 7t676323a is the ID of a customer who has several accounts registered with the bank. In response, the server returns IDs of two accounts, viz., AZA12093 and ADK31242, respective customer IDs and current balances, as below.
200 OK
Content-Type: application/xml;charset=UTF-8
<accounts xmlns="urn:org:bank:accounts">
<account>
<id>AZA12093</id>
<customer-id>7t676323a</customer-id>
<balance currency="USD">993.95</balance>
</account>
<account>
<id>ADK31242</id>
<customer-id>7t676323a</customer-id>
<balance currency="USD">534.62</balance>
</account>
</accounts>
Let me assume that an XML schema bound to an urn:org:bank:accounts namespace describes the XML documents used in this example.
Step 2: Since the client knows the IDs of both accounts, if necessary, it can submit GET requests to the following URIs to obtain more information of each account.
http://bank.org/account/AZA12093 http://bank.org/account/ADK31242
For this example, as the client has the information it needs to initiate an account transfer, let me skip these requests.
Step 3: The client then issues an account transfer by submitting a POST request as follows.
POST /transfers
Host: bank.org
Content-Type: application/xml;charset=UTF-8
<transfer xmlns="urn:org:bank:accounts">
<from>account:AZA12093</from>
<to>account:ADK31242</to>
<amount currency="USD">100</amount>
<note>RESTing</note>
</transfer>
The server retrieves routing numbers for the accounts, and submits the transfer to some bank-end system to execute the transfer, and returns the following.
201 Created
Content-Type: application/xml;charset=UTF-8
<transfer xmlns="urn:org:bank:accounts">
<from>account:AZA12093</from>
<to>account:ADK31242</to>
<id>transfer:XTA8763</id>
<amount currency="USD">100</amount>
<note>RESTing</note>
</transfer>
The transfer is not done yet. The transfer is going to happen asynchronously over a couple of business days (not unusual for inter-bank transactions), and the client can use the ID of the transaction to find out its status.
Step 4: A day later, the client submits a GET request to find the status.
GET /check/XTA8763
Host: bank.org
200 OK
Content-Type: application/xml;charset=UTF-8
<status xmlns="urn:org:bank:accounts">
<code>01</code>
<message xml:lang="en">Pending</message>
</status>
Note that, although this implementation uses resources, URIs, representations, and HTTP's uniform interface, it is not RESTful. As we will see in the next section, this example does not take advantage of one of the key constraints of REST, viz., that hypermedia be the engine of application state.
Before attempting to make this RESTful, let me try to write a possible user documentation to accompany this example.
Bank.Org API - URIs
http://bank.org/accounts?findby=someparamsSubmit a GET request to this URI to search bank accounts. This will return an
accountsdocument. See the XML schema for more details.
http://bank.org/account/{account-id}Submit a GET request to this URI to get account details. Here
{account-id}is the ID of the account. This will return anaccountdocument. See the XML schema for more details.
http://bank.org/transfersSubmit a POST request to this URI to create an account transfer. In the body of the request, include the
transferdocument. If the request is successful, the server will return atransferdocument. See the XML schema for more details.
http://bank.org/check/{transaction-id}Submit a GET request to this URI to find the status of the transfer. Here,
transaction-idis the ID of the account transfer. This will return astatusXML document. See the XML schema for more details.
This style of documentation is the most common today. It includes all the URIs that the client will ever need to use. It describes HTTP methods that clients can use with each URI. It also includes descriptions of representations, viz., the XML documents in this example.
But There are two problems with this style of documentation. First of all, it does not help any one looking for a formal machine-readable description. Without a machine-readable description, we can not build generic software tools that can test or otherwise enforce the contract. The lack of such generic software tools is of considerable impediment for those that need to deploy such tools for managing and governing their software. You may consider using WADL, or even WSDL 2.0 to provide a machine-readable equivalent.
Secondly, and more importantly, describing the server's interface in this manner, whether machine-readable as WADL or WSDL 2.0, or human readable, violates two of the constraints of REST that require that (a) messages be self-describing, and (b) hypermedia be the engine of application state. How so and why does it matter?
The key constraints of REST are (a) identification of resources, (b) manipulation of resources through representations, (c) self- descriptive messages, and (d) hypermedia as the engine of application state.
Messages in a RESTful application using HTTP are self-describing by virtue of two things, firstly, by the use of the stateless uniform interface, and secondly, by the use of HTTP headers that describe the contents of messages in addition to implementing various protocol aspects of HTTP such as content negotiation, conditional requests for caching and optimistic concurrency and so on.
By looking at the HTTP method used, and the request/response headers, an intermediate entity such as a proxy or cache can decipher which part of the protocol (viz., HTTP) is being used and how. Such self-describing messages ensure that client-server interactions are visible (e.g. to caches), reliable (e.g. detecting and recovering from partial failures) and scalable.
The fourth constraint, viz., that hypermedia be the engine of application state serves two purposes. Firstly, it relieves the protocol (viz., HTTP) from being stateful. Secondly, it allows the server to evolve (e.g. by introducing new URIs) and keeps clients loosely coupled to servers.
When a server is providing a description of representations as in previous section, it is not taking advantage of the self-describing nature of HTTP. In HTTP, clients and servers use "media types", or those Content-Type headers that we see in requests and responses to describe contents of messages, and not XML schemas. A media type is a like the class of an object, or the schema type of an XML element.
Further, when a server is describing all URIs to its clients, it will not be able to evolve on its own, and its interface becomes brittle. Any changes to URIs will most likely break existing clients. But then, how can you write a client without knowing the URIs that it needs to connect to?
The answer lies in using links with known relations. A link is an indirection that a client can use to discover URIs at runtime. A link has at least two properties - a URI, and a relation. The URI points to a resource, or a representation of a resource, while the relation describes the type or kind of the link. A true RESTful server application conveys URIs to clients by including links with predefined relations in its representations. So, instead of having to learn all URIs a priori, the client can extract URIs from links at runtime. Consequently, the server is free change URIs or even introduce new URIs on the same or some other server that provide a compatible behavior.
Finally, links that a server returns in representations can be contextual, by directing what the client can do subsequently. In other words, links dynamically describe the contract between the client and the server in the form of a workflow at runtime.
To sum up, for a RESTful application, the contract contains three different pieces: the uniform interface, media types of representations, and contextual links to resources.

Sounds like a fairy tale? Let me rewrite the above example to show the contract in action.
Step 0: Same as before.
Step 1: The client uses the same URI http://bank.org/accounts?findby=someparams to search for the accounts. This time, let the server return a different kind of response.
200 OK
Content-Type: application/vnd.bank.org.account+xml;charset=UTF-8
<accounts xmlns="urn:org:bank:accounts">
<account>
<id>AZA12093</id>
<link href="http://bank.org/account/AZA12093" rel="self"/>
<link rel="http://bank.org/rel/transfer edit"
type="application/vnd.bank.org.transfer+xml"
href="http://bank.org/transfers"/>
<link rel="http://bank.org/rel/customer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/customer/7t676323a"/>
<balance currency="USD">993.95</balance>
</account>
<account>
<id>ADK31242</id>
<link href="http://bank.org/account/ADK31242" rel="self"/>
<link rel="http://bank.org/rel/transfer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/transfers"/>
<link rel="http://bank.org/rel/customer"
type="application/vnd.bank.org.customer+xml"
href="http://bank.org/customer/7t676323a"/>
<balance currency="USD">534.62</balance>
</account>
</accounts>
In this response, note the value of the Content-Type header, and the links containing URIs.
Step 2: If the client wants to find out more about each account, it can extract their URIs from the links of "self" relation from the above response, and submit GET requests to those URIs.
Step 3: In order to initiate an account transfer, the client extracts the URI from the link with "http://bank.org/rel/transfer" and "edit" relations from either of the accounts above, and submits a POST request to it.
POST /transfers
Host: bank.org
Content-Type: application/vnd.bank.org.transfer+xml;charset=UTF-8
<transfer xmlns="urn:org:bank:accounts">
<from>account:AZA12093</from>
<to>account:ADK31242</to>
<amount currency="USD">100</amount>
<note>RESTing</note>
</transfer>
Again, note the value of the Content-Type header.
After initiating the account transfer, the server returns the following.
201 Created
Content-Type: application/vnd.bank.org.transfer+xml;charset=UTF-8
<transfer xmlns="urn:org:bank:accounts">
<link rel="self"
href="http://bank.org/transfer/XTA8763"/>
<link rel="http://bank.org/rel/transfer/from"
type="application/vnd.bank.org.account+xml"
href="http://bank.org/account/AZA12093"/>
<link rel="http://bank.org/rel/transfer/to"
type="application/vnd.bank.org.account+xml"
href="http://bank.org/account/ADK31242"/>
<link rel="http://bank.org/rel/transfer/status"
type="application/vnd.bank.org.status+xml"
href="http://bank.org/check/XTA8763"/>
<id>transfer:XTA8763</id>
<amount currency="USD">100</amount>
<note>RESTing</note>
</transfer>
Step 4: To find the status of the account transfer, the client can extract the URI from the link of relation "http://bank.org/check/XTA8763" and submit a GET request to it.
This implementation is RESTful as it uses representations with contextual links to encapsulate the state of interactions, i.e., it takes advantage of the constraint that hypermedia be the engine of application state.
Now, let me take a step back and highlight the information required to implement the new set of interactions. To start with, the client needs to know the URI to search for accounts. It then needs to know the names and semantics of various link relations. It also needs to know the details of each media type. It can figure out the rest of the contract dynamically at run time. We can therefore come up with the following revised documentation.
Bank.Org API
URIs
http://bank.org/accounts?findby=someparamsSubmit a GET request to this URI to search bank accounts. You can pass customer ID or customer name or customer's social security number as the value of the
findbyquery parameter. This resource supportsapplication/vnd.bank.org.accounts+xmlmedia type.Link Relations
selfThe URI of a link with this relation refers the containing resource, such as account and transfer resources.
http://bank.org/rel/transferandeditThe URI of a link with these relations can be used to create a new account transfer resource.
http://bank.org/rel/customerThe URI of a link with this relation can be used to fetch a customer resource.
http://bank.org/rel/transfer/fromThe URI of a link with this relation identifies the source account resource for the transfer.
http://bank.org/rel/transfer/toThe URI of a link with this relation identifies the target account resource for the transfer.
http://bank.org/rel/transfer/statusThe URI of a link with this relation can be used to fetch the status resource.
Media Types
application/vnd.bank.org.accounts+xmlA representation of this media type contains an
accountsdocument declared in the namespaceurn:org:bank:accounts. See the XML schema for more details.
application/vnd.bank.org.transfer+xmlA representation of this media type contains a
transferdocument declared in the namespaceurn:org:bank:accounts. See the XML schema for more details.
application/vnd.bank.org.customer+xmlA representation of this media type contains a
customerdocument described in the namespaceurn:org:bank:customer. See the XML schema for more details.
application/vnd.bank.org.status+xmlA representation of this media type contains a
statusdocument described in the namespaceurn:org:bank:transfer. See the XML schema for more details.
The approach to describing applications RESTfully that I presented in the previous section has some odd as well as some interesting characteristics.
For those familiar with WSDL and WADL, the description in the previous section may look unconventional. Instead of descriptions of input and output messages for every operation, we see media types. However, since generic media types such as application/xml are too generic to help us distinguish representation of an account resource from a representation of a customer resource or a transfer resource, in this example I used custom media types. Each of these media types ends with "+xml", and as per RFC 3023, XML processors (including XMLHttpRequest) can handle such representations as though it is XML. By looking at such media types, the client knows whether it received a representation of an account resource or a transfer resource. More importantly, it does not have to assume anything about the structure or syntax of the URI it used to fetch that representation.
Moreover, instead of listing all the URIs that the application is using, the documentation included just the one URI that the account transfer client needs to start interacting with. Note that, in a different example, we may need to document more than one URIs. The idea is to pre-publish the smallest number possible. Why is this better? It decouples the client from the actual URIs of resources, and the client does not need to know the rest of the URIs until run-time.
Finally, the documentation above did not include HTTP operations applicable for each URI. Instead, I assumed that the client submits an HTTP OPTIONS request on each URI to discover various operations possible, and then uses HTTP GET to get a representation of a resource, HTTP POST to create a new resource in a collection of resources, HTTP PUT to update an existing resource (or create one if the client can assign a URI for the resource), and HTTP DELETE to delete a resource.
To sum this up, describing the contract RESTfully involves the following:
Such a description is neither complete nor fully machine-readable.
It is not complete since it just includes the static aspects of the contract, leaving the server to describe the possible workflow at runtime via links.
For those that are already convinced about the benefits of REST and are actively building RESTful applications using HTTP, lack of a completely machine-readable description may not matter.
But for those that are building distributed applications using RPC-like approaches using SOAP, WSDL, and WS-*, and are considering REST, lack of a completely machine-readable description may appear like a show-stopper. However, the amount of work that can be done using a RESTful machine-readable description, if one exists today, is limited. This is due to the following:
Also note that a completely machine-readable description of a contract for a remote interface is a fallacy. A machine-readable description created by using WSDL or WADL can only describe the structure and syntax, but not semantics. But machine-readable descriptions can sometimes help us reduce the amount of work that we, as programmers, testers and administrators, need to do.
If we leave aside the uniform interface and the dynamic aspects of the contract, we can describe the rest of the contract in a machine-readable manner. Here is an example. Note that my intent in this description is only to help tools and frameworks that want to monitor or test client-server interactions, but certainly not to mimic WSDL or WADL.
<description xmlns:bank="urn:org:bank:accounts">
<types>
<!-- Include the schema used for all representations -->
<include href="bank-schema.rng"/>
</types>
<!-- List all media types and the corresponding XML types -->
<media-types>
<media-type>
<name>application/vnd.bank.org.accounts+xml</name>
<representation>bank:account</representation>
</media-type>
<media-type>
<name>application/vnd.bank.org.transfer+xml</name>
<representation>bank:transfer</representation>
</media-type>
...
</media-types>
<relations>
<relation>
<documentation>This relation ...</documentation>
<name>http://bank.org/rel/transfer</name>
</relation>
...
</relations>
<resources>
<resource>
<name>accounts</name>
<media-type-ref>application/vnd.bank.org.accounts+xml</media-type-ref>
<uri> <!-- This is optional -->
<base>http://bank.org/accounts</base>
<params>
<param>
<documentation>Use this parameter to ...</documentation>
<name>findBy</name>
</param>
</params>
</uri>
</resource>
<resource>
<name>transfer</name>
<media-type-ref>application/vnd.bank.org.transfer+xml</media-type-ref>
</resource>
...
</resources>
</description>
This is a machine-readable version of the one I described in the previous section, and is certainly not governed by any standard. This description does not eliminate the need for human-readable description, since we still need that to describe the semantics of the application.
Let me highlight the key sections of this description:
Is this kind of a description more useful than the human-readable description? In the absence of tools and frameworks that can interpret such a description, the answer may be no.
If you are writing the server-side code and the client-side code based on a machine-readable contract such as a WADL document, the coding flow may be as follows:
This model won't work for a RESTful description of the contract, and the steps would be different.
href and type (if present) attributes for later use.Most software frameworks that I am aware of can deal with some of the steps above, such as common interfaces or conventions for resource classes, and depending on your programming language of choice, be able to generate classes to create or parse XML. But the rest is left up to the developer. More over, most of these frameworks emphasize server-side development, and leave out client-side development under the assumption that existing HTTP client libraries are sufficient. Consequently, you may need to create custom code to deal with items (4) and (5) above.
How about software tools that want to test or enforce the contract? It is possible to create such software that reads the above machine-readable description to do the following at runtime.
I am not aware of any software that can validate these in this manner. However opportunities abound. If you have read this article this far, you know what those opportunities are.
One of my goals for this article is to illustrate the fact that traditional descriptions of contract such as WSDL and WADL are not adequate to describe RESTful applications. As I demonstrated with the account transfer example, only a part of the contract can be described statically, and the rest is dynamic and contextual. The client can follow this dynamic part of the contract at runtime by looking at links. You can attempt to describe the former via some machine readable document for design-time or testing purposes, but letting the server describe the rest at runtime reduces the coupling between clients and servers significantly. Attempting to describe the complete contract statically is equivalent to duplicating all the contextual links outside representations.
In contrast, description languages like WSDL and WADL try to describe the contract in a context-free manner, and client developers are left to user documentation to learn how to compose a client application from various message exchange patterns described in those descriptions. In RESTful applications, servers provide this information at runtime in the form of links.
To conclude, RESTful applications do have a contract. We just need to what to look for and where, and remember that the contract is contextual.
Subbu works at Yahoo. See his blog for more about him.
Would you enroll in an India Forex Group i.e http://www.indiaforex.com Groups?
Subbu,
Nicely written article on REST. Your bank.org examples clearly explain how to improve a RESTful design to exhibit full self-describing contracts.
I agree with you that the lack of a universal contract language could be a show stopper for some developers given that it increases the amount of manual development required to bind to the RESTful interface. Variances in RESTful contracts between vendor APIs also diminishes the number of universal tools that can be created to ease the binding for client software. A lack of a universal contract language for REST also means that there is a burden to write code to construct the contract and distribute it through HTTP OPTIONS on the server side. However, given these limitations, the approach still has its positives based on flexibility and simplicity.
There are a couple of REST-like frameworks. In Java there the free, open source framework called Restlet [1] that now nicely integrates with GWT. In the .NET world, Microsoft has created an free framework called ASP.NET MVC [2] that embraces the power of HTTP and the URL. However, for Subbu's demonstration with his RESTful self-describing contracts there is currently no framework for it (at least that I'm aware of anyway). You'll have to role your own. Without a universal way of describing RESTful contracts it hampers the ability to write consistent frameworks that work on various platforms. That being said, I believe that Subbu has laid down a great foundation that others can build upon and hopefully evolve towards a formal base that everyone can work off of.
[1] http://www.restlet.org/
[2] http://www.asp.net/mvc/
Michael: MVC has nothing to do with REST. MVC binds URLs to actions ("{controller}/{action}/{id}"). This is clearly explained in their tutorial: http://quickstarts.asp.net/previews/mvc/mvc_RoutingInMvc.htm The MVC pattern is not resource oriented by any means. At the end of the day there are several models that needs to be very clear: - Web Services: one endpoint per service (any number of operations) - MVC: one endpoint per action - REST: one endpoint per resource - Pub/Sub: one endpoint per queue Each of these approaches allow you to associate business logic to an endpoint (they also have different activation and concurrency models). The resulting factoring of this business logic is quite different in each case.
Subbu, This is nicely written. It felt analogous to "how can a machine-client browse"! Is there a typo in the rewritten example under Media Types for Status? Shouldn't it be: application/vnd.bank.org.status+xml
This article is one of the few that clearly articulate what is meant with "Hypermedia as the engine of application state" - I really appreciate this. However, I don't agree with the usage of HTTP options. Except for some "automated RESTful crawler", I don't see why any client application should do this. Except for a PUT intending to create a resource, which could be replaced by POST, you cannot interchange the verbs anyway. And even that replacement is somewhat fishy, as I assume that in most cases, the intended URL has at least *some* business value. In that manner, changing the allowed verbs will definitively break the client code.
Wondering how you feel about link@rel described by a uri template rather than a uri. The reason is that in my system, you can create new entity sub-types runtime, then assert a parent-child relationship between them (also runtime).
It is an atompub-based content management system. A "collection" can have item types, e.g. "artist" and "artist work" (these item types are not predefined, by constructed runtime). We can then assert artist has (0:m) works -- we do so by posting a "relation" resource to the appropriate endpoint. Then we create relationships by attaching an atom:category to the child instance (e.g. on entry for "starry night" we add category
Come to think of it, as long as the documentation (or service description) can be generated runtime -- no need for uri templates in docs. Just documentation of the link@rel that points to the end point for creating new type-to-type relations. In AtomPub, I use app:categories to "document" the new relations as categories@scheme (which becomes a link@rel when used as I described above). --peter keane
Jean-Jacques, I believe Michael was alluding to Microsoft Astoria... Cheers, Zubin Wadia CTO www.imagework.com "Business Acceleration through Process Automation."
Thanks. You are right about the typo. I will get it corrected.
@Michael: There is a universal contract "language" for RESTful apps, and that involves the uniform interface, media types, and link relations. A client that "understands" the uniform interface, some URIs to start with, and a given set of media types and link relations should be able to function just based on these.
I agree, and would add one more correction: The uniform interface is not just a set of methods. Document types are _part_of_ the uniform interface. In a strictly pure REST architecture, all document types would be known by all components. Because documents on the Web have essentially one function (convey human-readable information), this is essentially possible. In environments where information has different purposes (purchase order versus employee record) the near-enough interpretation is that every component understands and knows how to generate every document type that makes sense. The service contract listed about should not describe the media type. That is the job of the architecture-wide standardisation process for the Uniform Interface. This standardisation process should result in a set of standard methods, true, but also a set of standard document types. What is left for the service contract to describe is the contextual meaning of any URLs that you want to "pre-publish". You want clients to know where to start from in whatever activity they are involved with. Past that point, documents should provide whatever contextual information is required to continue the client's task until it is complete.
@Benjamin: Agree that media types are part of the uniform interface but not necessarily in the same way you imply. Uniform interface requires that media types make messages self-describing, but the interface itself does not have to describe what the media types are. Secondly, whether media types are described via some "architecture-wide standardization process" or not depends on the nature of applications. As the developer, of say, some new set of HTTP APIs for some next big cool thing, I may choose to define the define media types myself. In cases where there are interoperating applications, some process like to describe may define those types. So, media types are part of the contract, and who defines those types can vary on a case by case basis.
@Benjamin: Just realized that you may be referring to the uniform interface in its generic sense, where as I am using it in the HTTP sense.
For Sure, this article is one of the closest to Rest concepts I have read.
I agree with it and I think the proposed solution may be usable, practical.
Still, the WSDL comments need a little discussion. In particular, two comments made me think a little about WSDL and WS perception: first, WSDL as a violation of self-describing messages and Hypermedia as an application state engine; Second, WSDL and WS as RPC-like approach.
The main idea of all this (at last to me), is that the description of the application is not out of band, but part of the application itself. WSDL has been used as a design time description to create fixed clients. But the actual idea was to have WSDL describe a set of resources called services, at runtime. Thus, if you follow, WSDL is not just a contract, but an standard media type that has all the info and links to use the application. It contains the information to create more messages and also how those messages are sent and received.
Another misuse is the RPC interaction. Services are seen as methods you need to call, when they are actually endpoints (URLs) that receive messages with an specific media type (let's think SOAP, or even the SOAP body document), and must process them. The content of the message (its type) should be enough to determine what the server needs to do with it (that is, no method name should be needed).
What do you think?
William Martinez Pomares.
Architect's Thoughts
I'm trying to find out to do in similar situations, and since I already have a "data-centric approach" like
@William: That is an interesting interpretation of WSDL, but looking at the stated goals in WSDL spec, I don't think WSDL was designed with such an interpretation in mind.
@Antonio: That's perfectly fine, although using a link like the ones in the examples would make linking more extensible.
Stefan just pointed out that the HTTP responses with 201 response code did not have the Location response header. This was an oversight. Thanks Stefan. Subbu
First, excellent article Subbu. Second, two typos I think.
Shouldn't this (sorry, the comment system gets rid of all leading whitespace)
Now that I've addressed the typos, I wanted to make a couple of observations:
1. Your examples drove home to me for the first time that a data architect using XML and now has THREE choices for representing a constituent of an XML doc: element, attribute, and now, link. For example, in the transfer document, one could have chosen to make the "note" a link to a note resource instead of an element. It would be interesting to see an analysis of which concerns would lead to the use of which style, ie element, attribute, or link.
2. I wonder why you chose to provide a transfer both an URN identifier (represented as an XML element
@Nick: a. I added "edit" just to quality the link. But it does not really matter, as long as the rel name is concrete enough to tell the client the type/purpose of the link. b. A typo. Thanks for a keen eye.
@Nick:
1. The choice is based on granularity and access patterns. If the server decided to inline it, but wants to tell the client the client that the inlined data could be accessed directly, it can provide a link with a self rel within that inlined element. If not, it could provide just a link making it a related/child resource. Simialarly, in the case of collections, we can think of collections containing just links to members, or include a summary+link for each member, or inline the entire member.
2. You are right. We discussed this a while ago. As I tried to illustrate at http://www.subbu.org/blog/2008/12/resource-identity-and-cool-uris, the URI in the self-link does not always uniquely identify the resource. When I say identity, I am looking from the client's point of view, which may want to store representations and need to come up with a database key. This is why Atom has an
re (a) either both account representations should have ""http://bank.org/rel/transfer edit" or neither should. As it is now, the 1st acct representation has "http://bank.org/rel/transfer edit", but the second has just "http://bank.org/rel/transfer". It makes the reader wonder why you are making a distinction.
re (2): One of the things I like about Google's BIGTABLE is that it was designed to use URLs as keys. Given a commitment to "cool URIs don't change", there is no reason that URLs can't be used for database keys.
@Nick: Re (2), the id is a URI, and a URL can be substituted as long as the app follows RFC 4287.
You may be also interested in looking to Project Jersey [https://jersey.dev.java.net/], a Java based implementation from SUN.
Fantastic article. I'm a non-IT/CS domain specialist who finds himself doing more and more programming. Your article answered a number of questions and confirmed a suspicion I hadn't yet seen a 'correct' REST description - RESTful now makes much more sense - Thank you! Still I like some ideas in WADL: - it is the documentation (extremely important) - grammars - provides an advanced starting point, even though it is not proper REST (remember my 'real-job'/domain-specialty is calling very minute) Having said all that what you describe is very elegant and hopefully will be amenable to code-gen by some framework. Some Questions. In your scheme the 'rel' attribute of a 'link' element is the (only?) brittle part, i.e. if the server side code changes this data, then the client side code has to be updated (manually or automagically). The benefit of the set-up you describe is that the server code can do what it likes with the 'href' location and the client code shouldn't break, or at least not so easily. Is this a fair summary? Next, in point 3 in your model under 'Is this practical', am I correct in thinking you'd 'create classes manually' which correspond to data in the 'rel' attribute in each link element? This 'rel' data was read in step 2 - correct? Thanks Mark
@Mark,
In your scheme the 'rel' attribute of a 'link' element is the (only?) brittle part, i.e. if the server side code changes this data, then the client side code has to be updated (manually or automagically). The benefit of the set-up you describe is that the server code can do what it likes with the 'href' location and the client code shouldn't break, or at least not so easily. Is this a fair summary?
Instead of URI in the href, the relation is part of the contract, and hence any changes to relations can break the contract. Imagine a web server deciding to use "myfeed" in place of "alternate" for a link to an Atom feed. That will all clients that are looking for that link.
Next, in point 3 in your model under 'Is this practical', am I correct in thinking you'd 'create classes manually' which correspond to data in the 'rel' attribute in each link element? This 'rel' data was read in step 2 - correct?
Code generation depends on the media types that the server is supporting for each resource. If those media type specifications do have provisions for code generation, so be it. But the rel data itself may not give enough clue for a code-generation tool.
Thanks Subbu,
OK, so I understand that this means link@rel is the contract - is this contract immutable?
That is, would it be RESTless to write a client and its server to regard rel (or rev) alone as an 'insurance' contract.
E.g Scenario: A client holds on to a response long enough for the link@rel to be invalid - so now the contract is broken. What would be regarded as RESTful behavior:
a) Have the client refresh the stale response?
b) Have the server accept an enquiry about the correct link for rel?
The second option gives some fall back behavior, but I'm not sure if anything about this violates the REST objectives. This is an issue when regenerating the stale response is very time consuming, but getting the link updated is not expensive.
In case you are interested - rubywaves.com seems to aiming at an extensible resource focused framework, although it is early days.
Mark
In your scheme the 'rel' attribute of a 'link' element is the (only?) brittle part, i.e. if the server side code changes this data, then the client side code has to be updated (manually or automagically). The benefit of the set-up you describe is that the server code can do what it likes with the 'href' location and the client code shouldn't break, or at least not so easily. Is this a fair summary?
Instead of URI in the href, the relation is part of the contract, and hence any changes to relations can break the contract. Imagine a web server deciding to use "myfeed" in place of "alternate" for a link to an Atom feed. That will all clients that are looking for that link.
Hmm, Having sketched out a client on paper I think I can now answer my own Q: a) Reason: Any 'insurance' contract makes no sense in REST since you cannot guarantee, from the current data, you can work out which path the client-server took to reach its current state, and that state, or at least a representation of it, may be embodied in any href's that are stale/broken.
This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.
This article explores the use of JBoss and jBPM to implement design solutions that effectively address the issue of orchestrating long running activities.
This presentation covers the use of graph databases as an optimal solution for data that is difficult to fit in static tables, rapidly evolving data or data that has a lot of optional attributes.
This session introduces Real Options and shows how it can help in running your project. Real Options is a decision-making process that can be used to manage risk.
This article discusses the use of bindings on services and references (including the instance of non-configured bindings) as the means to implement SCA communications in a Web and SOA environment.
After a short introduction to DSLs, Scott Davis plays with the keyboard showing how to approach the creation of a DSL by typing working snippets of Groovy code that get executed.
IBM Rational and InfoQ present, Scaling Agile with C/ALM, an eBook showing organizations how to become “finely tuned software delivery machines” by enabling team integration and scaling.
Amanda Laucher presents a real life enterprise application written in F#. She shows actual code snippets, explaining design decisions and suggesting how to use some of the F# constructs.
30 comments
Watch Thread Reply