RESTful Service - Ajax Patterns

RESTful Service

From Ajax Patterns

(Difference between revisions)
Revision as of 04:38, 30 July 2009
120.51.3.147 (Talk | contribs)

← Previous diff
Revision as of 11:48, 17 August 2009
62.58.152.52 (Talk | contribs)
XML Data Island - spam-b-gone
Next diff →
Line 322: Line 322:
A RESTful transaction often involves passing a resource back and forth, with each side augmenting its state. For instance, a server can deliver an initially empty shopping cart, the client can add an item to it, the server can set the total price, and so on. Instead of transforming to and from a custom data structure, it sometimes makes sense for the browser to retain incoming [[XML Message]]s and transform them according to the interaction. A RESTful transaction often involves passing a resource back and forth, with each side augmenting its state. For instance, a server can deliver an initially empty shopping cart, the client can add an item to it, the server can set the total price, and so on. Instead of transforming to and from a custom data structure, it sometimes makes sense for the browser to retain incoming [[XML Message]]s and transform them according to the interaction.
-[http://blogs.yahoo.co.jp/takotako_mecchauma 処女] 
-[http://www.actiblog.com/tomodachi/ メル友募集掲示板] 
-[http://yumanomerutomo.spaces.live.com/ メル友] 
-[http://plaza.rakuten.co.jp/miponpoko/ 援交] 
-[http://www.actiblog.com/wakaduma/ セックスフレンド] 
-[http://yaplog.jp/beautywife/ セフレ] 
-[http://ameblo.jp/tubasablo/ セフレ] 
-[http://ameblo.jp/tubasablo/bookmark.html セフレ] 
-[http://jyunsu.blog.so-net.ne.jp/ メル友募集] 
-[http://pinkypinky.blog3.petitmall.jp/ メル友] 
-[http://hidakkusu.hida-ch.com/ メル友] 
-[http://reggaerockaway.blogspot.com/ メル友] 
-[http://hamutarou.kitaguni.tv/ メル友] 
-[http://homesick.tamaliver.jp/ メル友] 
-[http://hitorigoto.saitamania.net メル友] 
-[http://songmailen.vox.com/ メル友] 
-[http://www.voiceblog.jp/deicyme/ メル友] 
-[http://d.hatena.ne.jp/takotako_mecchauma/ メル友] 
-[http://eijiokumura.jugem.jp SEX] 
-[http://majimenagakusei.cscblog.jp/ 援交] 
-[http://whatdoyouthink.della-nagoya.jp/ 援交] 
-[http://mousoutarou.blog.shinobi.jp/ セックスフレンド] 
-[http://blog.oricon.co.jp/mintonakimochi/ セックスフレンド] 
-[http://ayufashiondaisuki.arekao.jp/ セックスフレンド] 
-[http://jessicaalba.jugem.jp セフレ] 
-[http://karaagekun.dtiblog.com/ セフレ] 
-[http://sitappa.otemo-yan.net/ セフレ] 
-[http://sitappa.namjai.cc/ セフレ] 
-[http://novoyagenolife.ti-da.net/ セフレ] 
-[http://blog.livedoor.jp/deidarabocchii/ セフレ] 
-[http://plaza.rakuten.co.jp/rupansansei/ セフレ] 
-[http://iedekeijiban.tamaliver.jp/ 家出掲示板] 
-[http://blog.goo.ne.jp/rinkaninaritai/ セフレ] 
-[http://taxitaxi.cscblog.jp/ メル友] 
-[http://segyakudoctor.vox.com/ 逆援助交際] 
-[http://blog.goo.ne.jp/humanbging/ セックスフレンド] 
-[http://marionett.cscblog.jp/ メル友] 
-[http://blog.goo.ne.jp/kaoru_with_mucha/ 逆援助交際] 
-[http://plaza.rakuten.co.jp/coolmasashi/ セフレ] 
-[http://ainosennshi.blogspot.com/ 処女] 
-[http://sehumansefu.vox.com/ SEX] 
-[http://plaza.rakuten.co.jp/deisyduck/ SEX] 
- 
-[http://ant.mrsp.jp/meru/ メル友] 
-[http://bat.mrsp.jp/monokuro/ メル友] 
-[http://bear.mrsp.jp/kumasan/ メル友] 
-[http://bee.mrsp.jp/hachimitu/ メル友] 
-[http://buffalo.mrsp.jp/gogo/ メル友] 
-[http://cat.mrsp.jp/perushian/ メル友] 
-[http://cow.mrsp.jp/meru/ メル友] 
-[http://dog.mrsp.jp/ponyo/ メル友] 
-[http://duck.mrsp.jp/yellow/ メル友] 
-[http://fox.mrsp.jp/kon/ メル友] 
-[http://hawk.mrsp.jp/tomodachi/ メル友] 
-[http://jaguar.mrsp.jp/tiger/ メル友] 
-[http://human.mrsp.jp/being/ メル友] 
-[http://lion.mrsp.jp/king/ メル友] 
-[http://panda.mrsp.jp/sasa/ メル友] 
-[http://pig.mrsp.jp/baby/ メル友] 
-[http://rabbit.mrsp.jp/run/ メル友] 
-[http://rat.mrsp.jp/cute/ メル友] 
-[http://snake.mrsp.jp/metarugia/ メル友] 
-[http://spider.mrsp.jp/man/ メル友] 
-[http://swallow.mrsp.jp/tale/ メル友] 
-[http://swan.mrsp.jp/lake/ メル友] 
-[http://tiger.mrsp.jp/dragon/ メル友] 
-[http://whale.mrsp.jp/sea/ メル友] 
-[http://wolf.mrsp.jp/man/ メル友] 
-[http://zebra.mrsp.jp/shima/ メル友] 

Revision as of 11:48, 17 August 2009

Evidence: 3/3

Tags: API HTTP REST Standard Universal Web


Contents

Technical Story

Devi is producing a public website describing pharmaceuticals to the public. General public can download the drug data from the server and authorised users - such as drug manufacturers - can upload new information. It's envisioned that third-party applications will also connect to the web server and provide their own user-interfaces. For example, pharmacies will be able to use the information via their point-of-sale systems, and doctors will have access from their specialised consulting software. Devi opts to follow a RESTful architecture for all of the services exposed by the server. This makes it easy for the browser-side of her own web application to access the data and expose services in a standard manner.


Problem

How do you expose services on the web?


Forces

  • The browser-side of an Ajaxian application needs to call server-side services.
  • There might be more than one browser-side application sharing the same server-side service.
  • As well, it's often desirable for third-party applications to invoke the server-side service too.
  • With numerous different applications - and a variety of developers - accessing the service, it ought to be easy to use.
  • Taken as a whole, the server-based services in a single "application" form an Application Programming Interface ("API"). It's important that services work consistently within the API.
  • The basic architecture of the web does not force any type of service architecture -a given service could be implemented in a wide variety of styles.


Solution

Expose web services according to RESTful principles. Representational State Transfer (REST) is an architectural style - or "pattern" - guiding on the architecture of web services. Like "Ajax" itself, "REST" is a broad term and can be broken down into many smaller patterns. The description can't possibly do justice to the entire concept, but it's worthwhile being familiar with the REST approach.

Motivating REST

To motivate REST, let's consider a football service, where sufficiently authorised clients can read match records, upload new matches, correct existing matches, or delete matches. Stated like that, you could offer the services in many different ways, which will lead to a problem of consistency: how will developers know what to expect. Consider just a few ways that a client might upload new match details:

And we could go on. And then we could look at the other functions here. There are many possible ways to represent a single function. Is that a problem? You might argue it's not a problem at all - just decide on a convenient solution, create the service, and document its usage. That argument, however, is flawed:

  • You might assume that the browser script for your web application, and perhaps some known external clients, are the only users of your service, making it relatively easy to create and document any service. In fact, there are other entities involved: the web browser (e.g. Firefox) which impacts on issues like back-button handling and bookmarking; the web server (e.g. Apache) which impacts on issues like caching and compilation; network routers and caches all along the way; robot applications such as those crawling the web on behalf of search engines; personal web agents which trawl through the web on behalf of individuals. Your application will perform better and more reliably if you follow certain conventions that are common among these entities.
  • Ideally, a service should be intuitive and self-documenting: if a service is based on familiar conventions, you only have to specify the bare minimum for a developer to be able to use it. That's simply not possible if everyone chooses alternatives according to their own personal taste. The standards-based alternative usually trumps the alternative that is technically superior.

REST addresses these concerns. Just about any collection of services can be presented as a RESTful API, and by doing so, it gains the advantage of a familiar, intuitive, style.

Introduction to RESTful Principles

So much for abstract motivation: what exactly are the RESTful principles?

REST is centered around two basic principles:

  • Resources as URLs. A resource is something like a "business entity" in modelling lingo. It's an entity you wish to expose as part of an API. Almost always, the entity is a noun, e.g. a person, a car, or a football match. Each resource is represented as a unique URL.
  • Operations as HTTP methods. REST leverages the exising HTTP methods, particularly GET, POST, PUT, and DELETE. Note that the XMLHttpRequest object, and some wrapper libraries such as AjaxCaller, support all of these methods. If they're unfamiliar to you, consult the W3C HTTP 1.1 Specification.

Another way to say it: Any action an HTTP client can perform involves a URL and an HTTP method. In RESTful APIs, the URL represents a noun and the HTTP method represents one of several standard verbs.

How are the URL and HTTP method combined in practice? Returning to the example, a match is clearly an entity in this API. So REST says we create a scheme which will expose each particular match as a unique URL:

 http://example.com/matches/995

So far, pretty unambiguous. Anyone familiar with REST will always be driven to create a unique URL for each match. There might be differences of opinion about the precise naming, but the basic concept will always be the same if you follow REST. Now that we have this unique URL, we can implement many functions around it, by leveraging the standard HTTP methods.

  • To get match results, the client simply issues a GET call on the URL. GET is the standard way to perform queries on the resource indicated by the URL. The response format is not dictated by REST, but XML is common due to its self-describing and self-validating nature.
  • To delete the match, the client issues a DELETE call on the URL. DELETE is the standard way to delete a resource.
  • To update a match, the client builds a fresh match message and uploads it in as the body of a PUT command. PUT is the standard way to update a resource's value.
  • To create a new match, the correct action will depend on whether the client can guess what the match's URL will be. If the service just allocates the URL arbitrarily, perhaps based on an auto-incrementing counter, then the client won't be able to guess it. When that happens, the new match is POSTed to a URL like http://example.com/matches, and the server responds with the new match's URL (http://example.com/matches/995). On the other hand, the client might be able to guess the URL, based on a naming convention. If the client guesses the new match would have URL http://example.com/matches/2000/9/25, then it can simply PUT the new match to that URL.

So each HTTP method will cause a well-defined action on the resource represented by the URL it operates on. The methods can be compared to SQL commands: GET is like "SELECT", DELETE is like "DELETE", POST is like "INSERT" with an auto-generated ID, PUT is like "INSERT OR UPDATE IF EXISTS" with an ID specified.

Again, notice most of this is fairly unambiguous. True, you still have to decide on a precise URL convention and message formats, but that's fairly minimal. Just by declaring "this is a REST interface", you're conveying many implicit rules to a REST-savvy developer. Inform that developer of the URL and message conventions, and they'll be able to intuit most of the API. That's a great improvement over a roll-your-own API approach, where each detail must be explained piecemeal.

RESTful Principles

Now, let's look at the main REST principles in more detail.

URLs reflect resources

As explained in the previous section, each resource receives a unique URL. URLs generally look like nouns.

HTTP Methods reflect actions

As explained in the previous section, each HTTP method has a well-defined meaning when applied to a given URL. HTTP methods are verbs applied to the resources, which are nouns.

GET used for queries, and only for queries

GET calls should never change server state. When you perform a query of any kind, use GET. When your call will affect any data on the server, use one of the other methods. PUT, POST, and DELETE can all change state. There are some slight caveats here - for example, if viewing a resource increments a counter, does that constitute a change? Technically, yes; but commonsense says no, it's not a significant change to the underlying resource, so it's probably acceptable to change a counter in response to a GET request. Just be aware that the counter might not be 100% accurate; for instance, caches might not hit the server directly because it's a GET request.

If you learn nothing else about REST, be sure to learn this guideline. Of all the REST conventions, this is the best known and widely applied across the net. It also applies for conventional web aplplications using plain HTML and forms. Never let a GET request change data on the server. Witness the the debacle caused by the Google Accelerator interacting with non-RESTful services in mid-2005. The accelerator jumps ahead of the user and prefetches each link in case they should click on it (a non-Ajaxian example of Predictive Fetch). The problem came when users logged into non-RESTful applications like Backpack. Because Backpack deletes items using GET calls, the accelerator - in its eagerness to activate each GET query - ended up deleting personal data. This could happen with regular search engine crawlers too, though the issue doesn't tend to come up because they don't have access to personal accounts.

The reverse problem can happen too. GET requests are often cached, but not the other types of request. By using POST to perform a read-only query, you deny the possibility of caching in the browser, within the client's network, or on your own server.

Services should be stateless

In stateful interaction, the server remembers stuff from the past. For example, you could do this:

Greg's Browser: What's the next missing match result? Server: Match 995 is missing. Greg's Browser: OK, I'll start working with it. Server: OK, Greg's Browser, you're working with Match 995. Greg's Browser: Here's the result: bluebaggers 150, redlegs 60. Server: Thanks, I'll store "bluebaggers 150, redlegs 60" for Match 995.

That's difficult to test, because you have to set the whole history up to test any particular interaction. Also, you can't cache anything effectively because a query result might depend on what happened earlier. Furthermore, an objective of REST is to be able to switch clients at any time and receive the same result. If you switch "Greg's Browser" to "Marcia's Browser", the server will respond differently to the match result above, because it will assume Marcia's Browser is working on a different match number. While users are unlikely to switch browsers mid-conversation, other clients like caches and robots may well switch. Substitutability makes the networks more scaleable.

The upshot is that everything should be passed in at once. It's okay for the client to remember details about the conversation - REST says nothing about the client's activity - but the server must not. The server responses should be based on the server's global state and not on the state of the conversation.

Greg's Browser: What's the next missing match result? Server: Match 995 is missing. Greg's Browser: Here's the result for Match 995: bluebaggers 150, redlegs 60. Server: Thanks, I'll store "bluebaggers 150, redlegs 60" for Match 995.

So are cookies used at all? Yes, cookies can be used, but mainly for authentication. They should only affect if the user can make a call, but not how the server responds. If authentication fails, an appropriate response, such as a 401 Forbidden header, will result. If authentication succeeds, the same call will always have the same effect, independent of the client who made the call. So if Greg's Browser says "Get All Matches", Greg will see exactly the same thing as if the all-powerful administrator asked for the same thing, as long as Greg's allowed to see them. If the security policy forbids Greg from seeing all matches, Greg's query will be denied. What won't happen is for Greg to receive just a minimal list of his own matches - if that happened, the server would be using the cookie to determine the browser's response. To get a minimal list, the query must be explicit - "Get All of Greg's Matches" - and of course, it must be Greg or the administrator that issues this request. If Marcia made that request, she'd get an authentication error.

An alternative to cookies is to use HTTP Basic Authentication, but this doesn't work too well in an Ajaxian context, because you don't have any control over the UI. The browser will typically pop up a dialog box, whereas you probably want to integrate any authentication directly into the interface, especially if using a pattern like Lazy Registration. HTTP Digest Authentication does allow more flexibility, but browser and server support is limited. Thus, while HTTP authentication is seen as "more pure", cookies are a reasonable workaround, provided you use them only for authentication.

Services should be idempotent

"Idempotent" means that once you pass a message to service, there's no additional effect of passing the same message again. For example, consider a deletion message, "Delete Match 995". You can send it once, or you can send it ten times in succession, and the world will be the same either way. Likewise, a RESTful GET is always idempotent, because it never affects state. The basic conventions on GET/DELETE/PUT/POST, described above, are intended to support idempotency. Edit: POST cannot be defined as idempotent as it is intended, amongst other things, to support creation of resources. Clearly POSTing to a creation service multiple times would result in multiple resources. See also: http://rest.blueoxen.net/cgi-bin/wiki.pl?HttpMethods .

Embrace hyperlinks

In resource representations returned by GET queries, use hyperlinks liberally to refer to related resources. With judicious use of hyperlinks, you can and should break information down. Instead of providing one massive response, provide a reasonable quantity of information and link to further details.

Service documents itself

RESTful services can and should document themselves. The exact mechanism is not well-defined. But a couple of examples include:

  • Base URLs can explain how the service works. For example, in the example above, http://example.com/match/995 represents a particular match, but http://example.com/match represents no real entity, so its result could be an instructive document, in human-friendly language, with appropriate hyperlinks.
  • Error responses should also be in human-friendly language and with examples and hyperlinks.

Service constrains data formats

As an extension to the previous point, RESTful services rely on standards such as Document Type Definitions (DTDs) and XML Schema to verify data formats as well as document what's acceptable.

Handling arbitrary actions

The REST definition is especially geared for creation, reading, updating, and deleting (CRUD) operations. How about arbitrary actions, such as "Pause the printer" or "Email the catalogue to this user"? By definition, application-specific actions don't fit neatly with the standard REST actions. There will always be some pragmatic judgement required as to a suitably RESTful interface. A few possibilities have been mooted, with viewpoints varying:

  • Where you're trying to transform state, have the client compute the new state and PUT a specification of the desired state - a standard update operation. For updates that are complex or entail business logic, you can provide a read-only service - accessed with GET queries - to help the client compute the new state.
  • You can POST a message to the resource in question, for example, POST a "pause" message to a URL representing the printer.
  • The server can expose a stateless "processor" resource to perform the action, e.g. a printer controller, and have clients POST command-like messages there, with URLs referencing the resources to be acted upon.

Weighing Up REST

Being a broad architectural style, REST will always have different interpretations. The ambiguity is exacerbated by the fact that there aren't nearly enough HTTP methods to support common operations. The most common example is the lack of a search method, meaning that different people will design search in different ways. Given that REST aims to unify service architecture, any ambiguity must be seen as weakening the argument for REST.

Another issue is portability - while GET and POST are standard, you may encounter browsers and servers which can't deal consistently with DELETE, PUT, and others, if they're supported at all.

The main alternative to REST is RPC (see RPC Service]). RPC is equally broad in definition, but the essential idea is that services are exposed as procedures. You end up POSTing into verb-like URLs such as /match/createMatch?matchId=1995 instead of RESTful, noun-like URLs such as /match/1995. In fact, the difference is significant enough that some service providers, such as Amazon, actually provide separate APIs for each. As a general rule, any set of services could be exposed as either REST or RPC; it's just a question of API clarity and ease-of-implementation. Note also there is some overlap; as discussed in the RPC Service solution, RPC can still follow certain RESTful principles.

From an implementation perspective, REST and RPC differ in that REST requires some explicit design, whereas RPC tends to follow directly from the back-end software model. In the example, it's likely there will be a Match class with a createMatch() method - that's just how most server-side software gets done. So it's a no-brainer to tack on a /match/createMatch web service that mediates between the client and the back-end method. In fact, there are many frameworks that will completely automate the process for you.

With REST, there's no direct mapping between web service and backend implementation - an impedence mismatch. You need to take a step back and explicitly design your API to be RESTful. If you're following feature-driven design, the API is the first thing you'll produce anyway, since the design will be "pulled" by the needs of clients, rather than "pushed" from the available technology. Once you've designed the API, the web service implementation will effectively be a kind of Adaptor (see Gamma et. al) to the back-end services.

To summarise crudely:

  • Any web service functionality can be exposed as either REST or RPC. There's a good argument that REST APIs are somewhat clearer, though that view is far from universal.
  • REST APIs may be clearer, but they do require more design and maintenance because they tend to diverge from the back-end technology. However, adaptor-style implementations of this nature are quite easy, so the overhead is not substantial and often justified in the effort to provide a clean interface, unaffected by the incidentals of the back-end implementation.


Decisions


Real-World Examples

I'm not aware of any Ajaxian applications which access a RESTful interface on the server-side. Consequently, the example here is a public API which conforms closely to REST. Note that several prominent industry interfaces are not covered here, because though they promote themselves as RESTful, they tend to break quite a few basic principles. For example, Amazon's REST API. In industry parlance, REST is sometimes synonomous with "not SOAP" and it's sometimes assumed that an interface is RESTful as long as it uses GET for reads and POST for writes.

There is a small library for doing Ajax RESTfully with Ruby on Rails called Jester.

Blogger Atom

Atom is a feed protocol built around RESTful principles. Blogger offers a good description on its use of Atom in its public API. The API lets third-party applications read and change Blogger blogs. Blogger themselves could theoretically build an Ajaxian application that directly calls on the API.

A blog entry is one important resource in blogger's API. For example, entry ID 1000 for user 555 "lives at" http://blogger.com/atom/555/1000. So to read that entry, you just issue a GET on that URL. To change the entry there, you just PUT an XML document to the same URL. To add a new entry, you don't yet know its ID, so you POST to a URL containing only the user ID, viz. http://blogger.com/atom/555. Note that each of these operations uses HTTP Basic Authentication and runs over HTTPS.


Refactoring Illustration

Ajax Shop Demo

The Basic Ajax Shop Demo provides a web service to expose and manipulate store items and user shopping carts. In this demo, the cart and product services are refactored to become more RESTful. You can contrast this to the Refactoring Illustration in Restful Service. Note that some constraints make the RESTful service less than ideal here:

  • URLs would ideally be prefixed with http://ajaxshop.com, but because it's running within the Ajax Demo framework, the prefix is longer: http://ajaxify.com/run/shop/rest
  • URLs would ideally avoid query strings, for example preferring the path /content/Movies to the path /content?category=music. However, to make the demos easy to install they don't use URL-rewriting, and so the paths do contain query strings.

There are three resources: categories, items, and carts. GET is used to read each of these. Only carts can be modified, either by adding an item or clearing the cart. Both of these are handled by POST, rather than PUT, since they are changes rather than replacements. Let's look at each service in more detail.

Reading Categories List

An XML list of categories is exposed by GETting http://ajaxify.com/run/shop/categories.phtml. Here, categories is the resource and the HTTP method is GET since we're reading the resource. To avoid listing all category information here, there's a link to each specific category resource.

 <categories>
   <category xlink="http://ajaxify.com/run/shop/rest/category.phtml?name=Books">Books</category>
   <category xlink="http://ajaxify.com/run/shop/rest/category.phtml?name=Songs">Songs</category>
   <category xlink="http://ajaxify.com/run/shop/rest/category.phtml?name=Movies">Movies</category>
 </categories>

Reading an Individual Category

To drill down to an individual category, say "Movies", you GET http://ajaxify.com/run/shop/category.phtml?name=Movies, which provides the name and items. Since an item is defined solely by its name, and we can't perform operations on items themselves, there's no need to give it a URL.

 <category>
   <name>Movies</name>
   <item>Contact</item>
   <item>Gattaca</item>
   <item>Solaris</item>
 </category>

As the system scales up, the list of all items gets excessive for someone who just wants to know the category name. So the next service provides just the items. If we wanted, we could then remove the list of items in the category name.

Reading Items

To read all the items for a category, you GET http://ajaxify.com/run/items.phtml?category=Movies.

 <items>
   <item>Contact</item>
   <item>Gattaca</item>
   <item>Solaris</item>
 </items>

Reading Cart Contents

Being RESTful, we can't just access the shopping cart out using the current session - each operation must specify the cart's owner. The session is used, but only for authentication.

To read the shopping cart of user 5000, we GET http://ajaxify.com/run/shop/rest/cart.phtml?userId=5000.

 <cart>
   <item>
     <name>Hackers and Painters</name>
     <amount>2</amount>
   </item>
   <item>
     <name>Accidental Empires</name>
     <amount>4</amount>
   </item>
 </cart>

To test the authentication, visit the web application http://ajaxify.com/run/shop/rest and add a few items. Cut-and-paste your assigned user ID over the "5000" in the above URL. You'll be able to see your cart. Then try a different user ID, say 6000, and you'll be greeted with the following message along with a 401 (Forbidden) header.

 You don't have access to Cart for user 6000.

Changing Cart Contents

Being RESTful, the cart URL remains the same whether we're manipulating or reading it. So when we make changes to user 5000's cart, we use the same URL as for reading it, http://ajaxify.com/run/shop/rest/cart.phtml?userId=5000 (which would instead end with the cleaner /cart/5000 if we could use URL-rewriting).

To update the cart, we simply PUT a new cart specification to the cart's URL. If the user's just cleared the cart, the following will be uploaded:

 <cart>
 </cart>

If the user's added an item, the browser still does the same thing: just upload the whole cart, e.g.:

<cart>
  <item>
    <name>Hackers and Painters</name>
    <amount>2</amount>
  </item>
  <item>
    <name>Accidental Empires</name>
    <amount>5</amount>
  </item>
</cart>

Note that the working with PUT is quite similar to working with POST. As explained in XMLHttpRequest Call, XMLHttpRequest has a requestType parameter. In the example here, the details are in any event abstracted by the AjaxCaller wrapper library:

 ajaxCaller.putBody(
     "cart.phtml?userId="+userId, null, onCartResponse, true,
     null, "text/xml", cartXML);

How to mail the cart contents is more subjective, as discussed in the "Arbitrary Actions" section in the Solution. The approach here is to post an email address to the cart URL, e.g.

<email-address>
 ajaxmail@example.com
</email-address>



Supporting PUT and DELETE in the server depends on the programming environment. In Java, for example, it's trivial because servlets contain doPut() and doDelete() methods alongside doPost() and doGet() methods. PHP, on the other hand, gives special treatment to GET and POST. Not only are variables exposed with the $_GET and <tt>$_POST arrays, but the POST body is accessible with $HTTP_RAW_POST_DATA. To read the body of a PUT call, the service here has to read from the input stream, php://input:

  function readBody() {
    $body="";
    $putdata = fopen("php://input", "r");
    while ($block = fread($putdata, 1024)) {
      $body = $body.$block;
    }
    fclose($putdata);
    return $body;
  }

It's partly inconveniences like this that drive some developers to compromise and use POST as a substitute for PUT and DELETION.


Alternatives

RPC Service

RPC Service is an alternative to REST Service, as highlighted in the Solution above.


Related Patterns

Semantic Response

REST is often used to design an application-independent web service API. That being the case, responses tend to be of a semantic nature.

XML Message

XML Messages are often used as the format of a REST service's Semantic Response. XML is particularly appealing as it's standards-based, broadly supported and understood, self-documenting, and capable of self-verifying when used with DTDs and XML Schemas. XML Messages tend to appear as the body of PUT and POST calls as well as in responses.

XML Data Island

A RESTful transaction often involves passing a resource back and forth, with each side augmenting its state. For instance, a server can deliver an initially empty shopping cart, the client can add an item to it, the server can set the total price, and so on. Instead of transforming to and from a custom data structure, it sometimes makes sense for the browser to retain incoming XML Messages and transform them according to the interaction.