Wednesday, February 27, 2008

Book Review: RESTful Web Services

I'm currently reading the book RESTFul Web Services, by Leonard Richardson and Sam Ruby. Find it at http://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260.

This post summarizes what I'm learning from the book. Here is the book's basic premise:

Give me Some of that Flux Capacitor: Back to the Future

Many of today's most modern and successful web applications are beginning to adopt architectures that look more and more like yesterday's World Wide Web architecture, circa 1994. This is a good thing. In the beginning, there was HTTP, URI, and HTML. This was good. This post will explain why based on the arguments of the authors of this book. The basic architecture of the World Wide Web has been term REpresentational State Transfer (REST) by one of its principal architects, Roy Fielding.

From the REST article in Wikipedia, here is a basic definition of REST:

REST strictly refers to a collection of network architecture principles that outline how resources are defined and addressed. The term is often used in a looser sense to describe any simple interface that transmits domain-specific data over HTTP without an additional messaging layer such as SOAP or session tracking via HTTP cookies.

REST is About Resources and Their Addresses

To understand more, just visit the REST article in Wikipedia and read it before reading the rest of this post. In summary, the takeaway from that definition are these two key concepts:

  1. Resources
  2. Addresses

Remember that when we discuss REST and the WWW, we're talking about  creating, retrieving, updating, and deleting Resources and about specifying Addresses at which locate those resources.

How the WWWW Architecture Works via RESTful Principles

As explained above, I won't rehash details better explained already on the REST article in Wikipedia and in Roy Fielding's dissertation, but I will briefly summarize what REST is with a simple example.

All of us who use the web are already familiar with Resources and Addresses. The content of the article that describes REST on Wikipedia is in fact a Resource. it is a document resource full of HTML text and links to other documents. And, of course, this Resource has an Address, http://en.wikipedia.org/wiki/Representational_State_Transfer.

When you browse to the URL http://en.wikipedia.org/wiki/Representational_State_Transfer your browser issues a request with a command and an argument. If you have Live HTTP Headers installed for Firefox or a similar plugin for IE, you can spy on the details of this request. It looks like this:

GET /wiki/Representational_State_Transfer HTTP/1.1
Host: en.wikipedia.org
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
If-Modified-Since: Wed, 27 Feb 2008 16:18:00 GMT

As another example, when you are on the www.asp.net web site and you do an Advanced Search for forum posts on the keyword "Scottgu", your browser issues a POST command:

POST /search/default.aspx HTTP/1.1
Host: forums.asp.net

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://forums.asp.net/search
Cookie: __utma=57644090.77168603.1204177720.1204177720.1204177720.1; __utmb=57644090; __utmc=57644090; __utmz=57644090.1204177720.1.1.utmccn=(direct)|utmcsr=(direct)|utmcmd=(none); CommunityServer-UserCookie605740=lv=Fri, 01 Jan 1999 00:00:00 GMT&mra=Thu, 28 Feb 2008 00:48:36 GMT; CommunityServer-LastVisitUpdated-605740=; CSAnonymous=1cf2e1d1-51fe-4609-be1d-b4618c323b27; __utma=185208894.1130547723.1204177819.1204177819.1204177819.1; __utmb=185208894; __utmc=185208894; __utmz=185208894.1204177819.1.1.utmccn=(referral)|utmcsr=wiki.asp.net|utmcct=/|utmcmd=referral
Content-Type: application/x-www-form-urlencoded
Content-Length: 9138
__EVENTTARGET=ctl00%24bcr%24ctl02%24ctl00%24SearchButton&__EVENTARGUMENT=&__VIEWSTATE=<deleted>&ctl00%24bhcr%24SearchForm1%24ctl00%24TitleBarSearchText=&ctl00%24bcr%24ctl02%24ctl00%24Keywords=Scottgu

An Embarrassment of Riches: This is Your Grandfather's HTTP, But He Kept His Treasures From You!

Both GET and POST are called HTTP Methods, or HTTP Verbs. These are the two most commonly used and known HTTP methods. However, there are others that almost nobody talks about, except for people who are writing applications using a REST-based approach. You can read more about these at http://rest.blueoxen.net/cgi-bin/wiki.pl?HttpMethods 

The four most important HTTP methods are GET, PUT, POST, and DELETE. Summarizing what other tutorials will explain in more detail, it's safe to say you can see the correspondence between these methods and the SQL DML statements SELECT, INSERT, UPDATE, DELETE.

Note: The PUT method can actually serve as both INSERT and UPDATE, and POST's purpose is more amorphous. A great explanation of the comparison between these HTTP Methods and SQL CRUD operations is found here on Paul Downey's blog: http://blog.whatfettle.com/2006/08/14/so-which-crud-operation-is-http-post/ 

REST versus RPC

Below is a compete section from the Wikipedia entry about REST. This illustrates the difference between RESTful web services based on HTTP and RPC-based web services, based upon the SOAP protocol.

The statements below refer to REST in the context of Web Services, specifically as opposed to SOAP. Note that Fielding’s dissertation presents REST in the context of information and media access, not web services. It does not contrast REST to RPC (remote procedure call).

REST
Resources—Commands are defined in simple terms: resources to be retrieved, stored / get, set—difficult to do many joins
RPC
Commands—Commands are defined in methods with varying complexity: depending on “standard”—easier (?) to hide complex things behind a method
REST
Nouns—Exchanging resources and concepts
RPC
Verbs—Exchanging methods

A RESTful web application requires a different design approach from an RPC application. An RPC application is exposed as one or more network objects, each with an often unique set of functions that can be invoked. Before a client communicates with the application it must have knowledge of the object identity in order to locate it and must also have knowledge of the object type in order to communicate with it.

RESTful design constrains the aspects of a resource that define its interface (the verbs and content types). This leads to the definition of fewer types on the network than an RPC-based application but more resource identifiers (nouns). REST design seeks to define a set of resources that clients can interact with uniformly, and to provide hyperlinks between resources that clients can navigate without requiring knowledge of the whole resource set. Server-provided forms can also be used in a RESTful environment to describe how clients should construct a URL in order to navigate to a particular resource.

Example

An RPC application might define operations such as the following:

getUser()
addUser()
removeUser()
updateUser()
getLocation()
addLocation()
removeLocation()
updateLocation()
listUsers()
listLocations()
findLocation()
findUser()


Client code to access this application may look something like this:


exampleAppObject = new ExampleApp('example.com:1234')
exampleAppObject.removeUser('001')


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 resources


http://example.com/users/
http://example.com/users/{user} (one for each user)
http://example.com/findUserForm
http://example.com/locations/
http://example.com/locations/{location} (one for each location)
http://example.com/findLocationForm


Client code to access this application may look something like this:


userResource = new Resource('http://example.com/users/001')
userResource.delete()


Each resource has its own identifier noun. Clients start at a single resource such as the user resource that represents themselves, and navigate to location resources and other user resources. Clients work with each resource through standard operations, such as GET to download a copy of the resource’s representation, PUT to paste a changed copy over the top of the original, or DELETE to remove the data or state associated with the resource. POST is sometimes used interchangeably with PUT, but can also be seen as a “paste after” rather than a “paste over” request. POST is generally used for actions with side-effects, such as requesting the creation of a purchase order, or adding some data to a collection. Note how each object has its own URL and can easily be cached, copied, and bookmarked.


Uniform interfaces in REST and RPC

The uniform interface allows clients to access data from a range of resources without special code to deal with each one, so long as it is actually uniform. The content returned from a user resource could be the globally standard and RESTful HTML, a less RESTful industry standard representation such as UserML, or an unRESTful application-specific data format. Which content is returned can be negotiated at request time. The content could even be a combination of these representations: HTML can be marked up with microformats that have general or industry-specific appeal, and these microformats can be extended with application-specific information.

Uniform interfaces reduce the cost of client software by ensuring it is only written once, rather than once per application it has to deal with. Both REST and RPC designs may try to maximise the uniformity of the interface they expose by conforming to industry or global standards. In the RPC model these standards are primarily in the form of standard type definitions and standard choreography. In REST it is primarily the choice of standard content types and verbs that controls uniformity.


Notice the decoupling of Noun and Verb in the REST sample code section. This is clean, simple, flexible, and feels very much like working with a relational database in which you use those four basic commands, SELECT, INSERT, UPDATE, DELETE to operate on various different types of data. In the RPC sample, the same verb gets repeated and paired with every single type of noun.

Just imagine how insane you would feel writing SQL DML statements if you had to write table-specific operator statements for each table in your database? Don't forget, because they are table specific, you'd actually have to be writing the implementation code for those, perhaps in C, C++, or maybe even C# if you're using SQL Server 2005 which has .NET built in.


SELECT_User(LastName), SELECT_Book(Title)

FROM_User JOIN_User(ID) = JOIN_Book(UserID)



WHERE_Book(PublishDate > '1/1/1990') AND WHERE_User(LastName = 'Box')


If I had to write this terrifying code, in which I have to manually write C# code to create verb + noun commands for each action and table, I would surely welcome the day someone decided to decouple the verbs and nouns, giving me the ability to write this:


SELECT LastName, Title

FROM Users a INNER JOIN Book b ON a.UserID = b.UserID

WHERE PublishDate > '1/1/1990' AND LastName = 'Box'


Washing out Your Mouth with SOAP after Swallowing a Bitter Blue Pill


So when it comes to XLM Web Services, why is it that most of us, at least in the Java and Microsoft .NET universe, have been brought up to believe that SOAP, Simple Object Access Protocol is the correct way to implement XML Web Services? As this book argues, this may not be the case, and increasing numbers of web developers and large companies like Yahoo and Amazon have already boarded the REST bus. In some cases they've been riding it comfortably for years by now.


Paul Prescod provides an excellent summary of differences between SOAP and REST in his article Roots of the REST/SOAP Debate. In his article he cites a interesting quote by Don Box, one of SOAP's principal authors, and also the author of the quintessential Windows programming book Essential COM. In the quote, Box states that had XML Schema been completed in 1998, they never would have created SOAP in the first place! Here is the complete context of the quote, which details.



http://www.infoworld.com/articles/hn/xml/02/06/06/020606hnbox.html?s=rss&t%3b=news&slot%3b=3



Prior to his calling on developers to build applications, Box detailed the birth of SOAP in 1998, and how it came about as a result of a failed effort to provide DCOM for Unix developers.


"We're entering year five of SOAP. It's kind of interesting that what started as a kind of a sabbatical, fun project ... turned into this kind of monster. But be careful what you wish for is the moral of the story," said Box.
SOAP was Microsoft's "second run up the hill," following the DCOM-for-Unix effort, he said. Box was not a Microsoft employee when he helped develop SOAP.


"The first run up the hill was DCOM on Unix. Had DCOM on Unix succeeded, we would not be sitting in this room," said Box. The effort failed because it resembled Windows programming too closely for Unix purists, Box said.
SOAP, he said, arose out of an HTTP foundation, with HTTP being a protocol accepted by multiple development camps. XML also was critical.


"Really, the novelty of SOAP was simply saying we're going to take XML and make it work for data," Box said.
An upcoming version of SOAP, Version 1.2, needs to be the final version, Box said.

Box also stressed that XML Schema is the dominant technology for Web services. "Had XML Schema been done in 1998, we would not have done SOAP," he said.


"The reality is, XML Schema is the foundation for the rest of XML," said Box. Technologies such as XML Query take XML Schema "for granted, as a given," he said.


SOAP messages need to function with XML Schema, he said. "XML Schema is an inevitability. Resistance is futile. There is no point in not embracing this thing and I strongly encourage those of you who work in Web services technologies [to] make sure your story is straight" with respect to XML Schema, Box said.


Box also addressed some maligning of the UDDI (Universal Description, Discovery, and Integration) specification at the conference, saying it has the most opportunity for growth and that the upcoming Version 1.3 of UDDI hopefully will fix problems with identifiers.
"It's hard to talk about UDDI without taking an apologetic tone," Box said.


Top Developers and Corporations Concur: REST is BEST, SOAP is DIRTY.


If you don't believe that SOAP is too complicated, or you believe that REST sounds too simple, don't worry. You don't have to use it. That won't stop Amazon from using it. Or Yahoo. Or Flickr. Or Microsoft. Yes, Microsoft, but more on that next.


Take a look at Amazon's S3 Simple Storage service: http://www.amazon.com/gp/browse.html?node=16427261


Or, read about Yahoo's REST-only web services: http://developer.yahoo.com/faq/#rest


Flickr's REST documentation: http://www.flickr.com/services/api/request.rest.html


The list just goes on and on and on. Just Google it for more examples. Better yet, just take a look at the kinds of applications people are building on top of Amazon's Web Services platforms:


http://www.amazon.com/Success-Stories-AWS-home-page/b/ref=sc_fe_c_0_16427261_4?ie=UTF8&node=182241011&no=16427261&me=A36L942TSJ2AJA



Stop that REST Bus, Microsoft's Coming, and They're Bringing a Whole Bunch of Programmers


Now you will not hear much about it yet from their marketing engine since Visual Studio 2008, Windows Server 2008, and SQL Server 2008 are all the rage and focus at this time, but Microsoft's engineering team is playing catch up right now trying to capitalize these trends. Competent and competitive Microsoft shops should take heed and be prepared well in advance by studying and learning from the competitors and projects that the MS crew are embracing and extending at this time.


Microsoft's ASP.NET team has already released a preview of the ASP.NET 3.5 Extension, available at


Microsoft's ADO.NET Data Services: REST Based Web Services


To get a sneak peek at Microsoft's REST architecture for Web Services, take a look here: http://astoria.mslivelabs.com/


Here is the summary of the technology from the home page:



The new wave of web applications are built on technologies such as AJAX and Microsoft Silverlight that enable developers to build better, richer user experiences. These technologies bring a shift in how applications are organized, including a stronger separation of presentation from data.

ADO.NET Data Services (also known as Project code name “Astoria”) consists of a combination of patterns and libraries that enables any data store to be exposed as a flexible data service, naturally integrating with the Web, that can be consumed by Web clients within a corporate network or across the Internet. ADO.NET Data Services uses URIs to point to pieces of data and simple, well-known formats to represent that data, such as JSON and ATOM/APP. This results in data being exposed to Web clients as a REST-style resource collection, addressable with URIs that agents can interact with using standard HTTP verbs such as GET, POST, or DELETE.


For the system to understand and leverage semantics over the data that is surfacing, ADO.NET Data Services models the data exposed through the data service using a model called the Entity Data Model (EDM), an Entity-Relationship derivative. This organizes the data in the form of instances of "entity types", or "entities", and the associations between them.


Microsoft's MVC Framework for ASP.NET


Related to the ADO.NET Data Services is the MVC Framework, also part of the ASP.NET 3.5 extensions. Learn more about that here: http://quickstarts.asp.net/3-5-extensions/mvc/MVCOverview.aspx


Here is the summary of the MVC framework from that page:



The Model View Controller (MVC) architectural pattern separates an application into three main components: the model, the view, and the controller. The ASP.NET MVC framework provides an alternative to the ASP.NET Web-forms pattern for creating MVC-based Web applications. The ASP.NET MVC framework is a lightweight, highly testable presentation framework that (as with Web-forms-based applications) is integrated with existing ASP.NET features, such as master pages and membership-based authentication. The MVC framework is defined in the System.Web.Mvc namespace and is a fundamental, supported part of the System.Web namespace.

MVC is a standard design pattern that many developers are familiar with. Some types of Web applications will benefit from the MVC framework. Others will continue to use the traditional ASP.NET application pattern that is based on Web forms and postbacks. Other types of Web applications will combine the two approaches; neither approach precludes the other.

The MVC framework includes the following components:



  • Models. Model objects are the parts of the application that implement the domain logic. Often, model objects also retrieve and store model state in a database. For example, a Product object might retrieve information from a database, operate on it, and then write updated information back to a Products table in SQL Server.



  • Views. Views are the components that display the application's user interface (UI). Typically, this UI is created from the model data. An example would be an edit view of a Products table that displays text boxes, drop-down lists, and check boxes based on the current state of a Product object.



  • Controllers. Controllers are the components that handle user interaction, manipulate the model, and ultimately select a view to render that displays UI. In an MVC application, the view only displays information; the controller handles and responds to user input and interaction. For example, the controller handles query-string values, and passes these values to the model, which in turn queries the database by using the values.

--To Be Completed--