Chapter 9. Web Services

THE CONCEPT OF A WEB SERVICE HAS ALREADY BEEN INTRODUCED IN THE WEB SERVICE PATTERN, BUT the pattern leaves open many questions—for instance, what sort of messages will be sent to and from the service? How will the URLs look? How will the service relate to backend software? These are the kind of design and programming issues covered in this chapter.

RESTful Service is an overview of Representational State Transfer (REST), a popular set of patterns and idioms for consistent and intuitive web services. RPC Service has similar goals, but with a philosophy that leads to very different services. Neither REST nor Remote Procedural Call (RPC) are Ajax-specific, because they are general industry conventions for web services. However, the next pattern, Ajax Stub, is Ajax-specific, because it provides a convenient way to invoke RPC-style services from the browser.

The remaining patterns look at popular message formats used for communication between the browser and Web Services. HTML Message is a message in HTML form, usually sent from the server to be morphed directly onto the page. In contrast, the remaining messages are raw responses that usually can’t be displayed directly, and that may be transferred in both directions. They are Plain-Text Message, XML Message, and JSON Message.

RESTful Service

⊙⊙⊙ API, HTTP, REST, Standard, Universal, Web

RESTful Service
Figure 9-1. RESTful Service

Developer Story

Devi’s producing a public web site explaining pharmaceuticals to the public. The browser applications will pull down drug data from the server, and authorized users—such as drug manufacturers—will be allowed to 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 specialized consulting software. Devi opts to follow a RESTful architecture for all of the services exposed on the server. This makes it easy for the browser side of her own web app to access the data and exposes services in a standardized manner.

Problem

How do you expose services on the Web?

Forces

  • The browser side of an Ajax App 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—any given functionality could be exposed 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 the architecture of web services. Like “Ajax” itself, “REST” is a broad term and can be broken down into many smaller patterns and idioms (enough to fill up an entire book!). The explanation here can’t possibly do justice to the entire concept, but it’s worthwhile being familiar with the general principles of REST. Because REST is such a large topic, be prepared for the reality that most real-world systems you’ll encounter are only somewhat RESTful; they’ll follow some principles and break others. Some people are now making the distinction between “High REST”—sticking closely to REST—and “Low REST”—following just a couple of core REST guidelines (http://lesscode.org/2006/03/19/high-low-rest/).

Motivating REST: many ways to skin a call

To motivate REST, let’s consider a football service. Sufficiently authorized clients can read game records, upload new games, correct existing games, or delete games. We’ll assume your backend’s already written, but how would you offer it as a web service? How will client developers call it, and how will they learn about its interface?

To wit, following are a few random ways you might expose a game service—note that these aren’t necessarily RESTful!

And we could go on. And then we could look at the other functions here. The point is this: as a service designer, you have many options for representing a single function. Is that, in itself, a problem? You might argue it’s not a problem at all—just choose any old option, using some darts and a blindfold if need be. Then just create the service and document its usage—any competent developer will then be able to deal with it, right? That argument, however, is flawed on several counts:

  • You might assume that the browser script for your web app, 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, your application resides within a larger Internet ecosystem. Among the entities involved: the web browser (e.g., Firefox), which impacts issues like back-button handling and bookmarking; the web server (e.g., Apache), which impacts 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; and personal web agents that trawl through the Web on behalf of individuals. Your application will perform faster 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 have only 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 interface usually trumps the optimized interface that’s technically superior but based on unfamiliar conventions. There are thousands of web services available on the Internet; developers should be able to assess them and put them into action with as little effort as possible.

  • In the absence of any guiding principles, there’s a disturbingly high likelihood you’ll end up in tedious debates with colleagues over the most trivial issues, trying to arrive at an optimal API. (The blindfold and darts—or an impatient manager—would alleviate this kind of paralysis, but the other issues would still remain.)

So we’ve seen the argument for a convention-based approach to web services, but what’s the convention? REST is one such convention, consisting of many different guidelines, that has broad industry support. Just about any functionality can be presented as a RESTful API, and by doing so, it gains the advantage of a familiar, intuitive style. Many services on the Net already follow RESTful principles, to differing degrees. Also, many real-world entities such as browsers and caches tend to assume REST. These entities work better if REST is in place—a browser, for instance, might give better feedback; a cache will retain all the data that the programmer expected it to retain. And what will happen if REST is not in place? It’s probably not the end of the world, but you’ll find little things will go wrong and work in unexpected ways. For instance, hitting the browser’s Reload button might cause a purchase order to be resubmitted. Or a cache might end up caching data it shouldn’t, or it might not cache any data at all. Why these unfortunate events might occur will become clear as we learn about the RESTful principles.

Introduction to RESTful principles

So much for abstract motivation: what exactly are the RESTful principles (http://www.xfront.com/REST-Web-Services.html) all about? REST ultimately presents the server as a big blob of “resources” such as people, cars, or football games. Clients interact by inspecting and changing that state. Putting a purchase order on the server, for example, will trigger the server to affect the purchase described in the order. This contrasts with the Remote Procedural Call (RPC) approach, where the client would call a remote purchase( ) procedure. REST is based on data manipulation, RPC is based on procedural calls.

REST sees the universe as consisting of resources and operations performed on, and with, those resources. The resources and the operations can be represented as the HTTP concepts of URLs and call methods.

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, it’s a noun; e.g., a person, a car, or a football game. Each resource is represented with a unique URL. So when you say a RESTful URL, it will be a thing rather than an action.

Operations as HTTP methods

REST leverages the existing HTTP methods, particularly GET, POST, PUT, and DELETE. Note that the XMLHttpRequest object, and some wrapper libraries such as ajaxCaller (http://ajaxify.com/run/testAjaxCaller/), support all these methods. If they’re unfamiliar to you, consult the W3C HTTP 1.1 Specification (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html).

Another way to say it is in HTTP, any request a client can make involves a URL and an HTTP method. With REST, the URL is designed to represent a noun and the HTTP method always maps to one of several standard verbs, which will be performed against that noun.

How is the URL combined with the HTTP methods in practice? Returning to the example, a game is clearly an entity in this API. So REST says we create a scheme to expose each particular game as a unique URL—for example, http://example.com/games/995.

So far, this is all pretty unequivocal. Anyone familiar with REST will always be driven to create a unique URL for each game. 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 (http://rest.blueoxen.net/cgi-bin/wiki.pl?RestFaq#nid1UP).

  • To get game 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 it’s self-describing and self-validating nature.

  • To delete the game, the client issues a DELETE call on the URL. DELETE is the standard way to delete a resource.

  • To update a game, the client builds a fresh game message and uploads it as the body of a PUT command. PUT is the standard way to update a resource’s value.

  • To create a new game, the correct action will depend on whether the client can guess what the game’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 game is POSTed to a URL like http://example.com/games, and the server responds with the new game’s URL (http://example.com/games/995). On the other hand, the client might be able to guess the URL, based on a naming convention. If the client guesses that the new game would have URL http://example.com/games/2000/9/25, then it can simply PUT the new game to that URL.

  • To perform an arbitrary transaction, you’ll also use one or more of these standard methods. So maybe the client wants a way to double the winner’s score. In this case, there’s probably no special service—the client just reads the old match, updates it, and PUTs it back to the server. For more complicated transactions, you might design a new resource specifically to encapsulate the request (e.g., a “purchase order” resource), and the client will then be able to POST resources like this to the server. Many businesses work the same way—contracts/orders are passed around in order to request that things are done and to verify that they’ve been done. See the section "Handling arbitrary transactions" later in this chapter for more details.

In summary, 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, and PUT is like “INSERT OR UPDATE IF EXISTS” with an ID specified.

Again, notice how most of this is unequivocal. 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. Compare that to an ad hoc, roll-your-own API, where each detail must be explained piecemeal. Considering that there are thousands of web services out there, it soon becomes clear why REST is an attractive option.

RESTful principles

Let’s now 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.

REST doesn’t tell you what names to call your resources—there are infinite possibilities and the choice is up to you. They’ll often reflect your conceptual model of the system and look similar to your database table names.

HTTP methods reflect actions

With REST, each HTTP method indicates the kind of action to be performed. Moreover, the REST API designer doesn’t have to decide what each method means, because there are only a handful of methods, and REST standardizes the meaning of each—GETs for queries, POSTs for inserts, and so on, as explained above. Notice how resource names are not standardized in the same way. Businesses have different models, so you can’t standardize on those things. But REST is saying that you can indeed model the resources so that the set of required actions is standard, thus ensuring APIs are consistent with one another.

Fortunately, the standard HTTP methods—when combined with a well-designed URL and resource scheme—are enough to let a client express just about anything it needs to. It’s true that in an ideal world, there would be a few extra actions to make life a bit easier. For example, it would be convenient if there was a standard LOCK action to let a client deal exclusively with a particular resource.[*] However, you can still work around this by introducing a lock resource and letting clients lock things by manipulating those resources with the standard HTTP methods.

GET for queries, and only for queries

Refining the previous point, GET calls must be read-only. When you perform a read-only query of any kind, always use GET. Conversely, when your call will affect any data on the server, use one of the other methods: PUT, POST, and DELETE all change state. There are some caveats here—for example, if issuing a query ends up leaving a log message somewhere, does that constitute a change? Technically, yes; but common sense says no, it’s not a significant change to the underlying resource, so it’s acceptable to log the message in response to a GET request. Just be aware that the log might not read as intended; for instance, some clients will get the content from a cache, which means no log message will occur.

The reverse problem can happen too. GET requests are often cached, but the other types of requests are not. When you perform a query with POST, you deny the possibility of caching in the browser, within the client’s network, or on your own server.

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 (see the sidebar "The Backpack-Accelerator Incident" in this chapter).

Services should be stateless

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

Greg’s Browser: Give me the next game to work on.

Server: Work on game 995.

...

Greg’s Browser: Here’s the result: bluebaggers 150, redlegs 60.

Server: Thanks.

(Server stores “bluebaggers 150, redlegs 60” for game 995.)

The server here has an implicit conversational state; it remembers the game Greg’s working on. That makes testing harder, because you have to set the whole history up to test any particular interaction. Another problem is the fragile nature of the transaction; what if Greg’s browser fails and ends up requesting two different games? When Greg uploads the score, the server could easily misinterpret which game he’s talking about. Also, you can’t cache effectively because a query result might depend on something that 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 game result above, because it will assume Marcia’s Browser is working on a different game number. While users are unlikely to switch browsers mid-conversation, other clients like caches and robots may well switch. Substitutability makes networks more scalable.

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; i.e.:

Greg’s Browser: Give me the next game to work on.

Server: Work on game 995.

...

Greg’s Browser: Here’s the result for Game 995: bluebaggers 150, redlegs 60.

Server: Thanks, I’ll store “bluebaggers 150, redlegs 60” for Game 995.

So are cookies used at all? Yes, cookies can be used, but mainly for authentication. They should only determine whether or not the server will accept a call, by not in any way how the server will respond. 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 Games,” 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 games, Greg’s query will be denied. What won’t happen is for Greg to receive just a minimal list of his own games—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 Games”—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 Ajax 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. Consider the deletion message, “Delete Game 995.” You can send it once, or you can send it 10 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 earlier, are intended to support idempotency.

Services use 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, include a modicum of information and point to further information using resource identifiers.

Services documents themselves

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 earlier example, http://example.com/game/995 represents a particular game, but ttp://example.com/game 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.

Services constrain 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 to document what’s acceptable.

Handling arbitrary transactions

The REST definition is especially geared for creating—such as Amazon—reading, updating, and deleting (CRUD) operations. How about transactions and 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 judgment required as to a suitably RESTful interface. A few possibilities have been mooted, with viewpoints varying (http://rest.blueoxen.net/cgi-bin/wiki.pl?VerbsCanAlsoBeNouns):

  • If it makes sense to do so, reformulate the action as a standard persistence 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 standard HTTP methods to support common operations. The most typical 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 that don’t deal consistently with DELETE, PUT, and other methods.

The main alternative to REST is RPC (see RPC Service , later). It’s equally broad in definition, but the essential idea is that services are exposed at procedures. You end up POSTing into verb-like URLs such as /game/createGame?gameId=995 instead of RESTful, noun-like URLs such as /game/995. In fact, the distinction 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 backend software model. In the example, it’s likely there will be a Game class with a createGame( ) method—that’s just how most server-side software gets done. So it’s a no-brainer to tack on a /game/createGame web service that mediates between the client and the backend 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 impedance 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 middleware Adaptor (see Gamma et al., 1995) to the backend services.

To summarize 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 backend 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.

Real-World Examples

I’m not aware of any Ajax Apps that access a truly RESTful interface on the server side. Consequently, the example here is a public API that 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 (http://rest.blueoxen.net/cgi-bin/wiki.pl?HowAmazonsRESTComparesWithREST). In industry parlance, REST is sometimes synonymous with “not SOAP,” and it’s incorrectly assumed that an interface is RESTful as long as it uses GET for reads and POST for writes.

Blogger API

Atom is a feed protocol built around RESTful principles. Blogger offers a good description on its use of Atom in its public API (http://code.blogger.com/archives/atom-docs.html). The API lets third-party applications read and change Blogger blogs. Blogger themselves could theoretically build an Ajax App 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, just issue a GET on that URL. To change the entry there, 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—for example, http://blogger.com/atom/555. Note that each of these operations uses HTTP Basic Authentication and runs over HTTPS.

Code Example: AjaxPatterns RESTful Shop Demo

The Basic Shop Demo (http://ajaxify.com/run/shop/) employs an ad hoc web service to expose and manipulate store items and user shopping carts. In this demo, the cart service is refactored to become more RESTful. You can contrast this to the Refactoring Illustration in RPC 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 CGI-style variables and look like "/content/Movies" instead of /content?category=music. That’s not possible here because there’s no use URL-rewriting (to make the demos easy to install).

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>Gatica</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 want, we could then remove the list of items in the category name.

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 here, 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 userId="5000">
    <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 app 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 userId="65590">
    <item>
      <name>Hackers and Painters</name>
      <amount>2</amount>
    </item>
    <item>
      <name>Accidental Empires</name>
      <amount>5</amount>
    </item>
  </cart>

Note that working with PUT is quite similar to working with POST. As explained in XMLHttpRequest Call (Chapter 6), 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>

Alternatives

RPC Service

RPC Service (see later in this chapter) is an alternative to RESTful Service, as highlighted earlier in the "Solution.”

Related Patterns

XML Message

XML Messages (see later in this chapter) are often used as the format of a REST service’s response, and sometimes its input as well. XML fits well here because 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 the incoming XML Messages in an XML Data Island (Chapter 11) and transform it according to the interaction.

Unique URLs

Unique URLs (Chapter 17) also relates to URL design, though they differ in scope. Unique URLs relates to the URLs of the Ajax App itself, while RESTful Service involves the URLs of web services it uses. It’s sometimes said that “Ajax breaks REST” because many Ajax Apps have a single URL regardless of state. Ironically, though, Ajax actually facilitates REST by encouraging a clean API to service the browser application. As for the browser application, Unique URLs do help make an Ajax App a bit more RESTful, though that’s somewhat beside the point since it’s the web services that a client would want to use.

Metaphor

REST is often likened to Unix—with its consistent usage of pipes and filters—and to SQL—with its standard persistence and querying commands—but can also be compared to Windows-based GUI platforms. There are standard actions like “Cut,” “Paste,” and “Popup Context Menu.” Each object (e.g., documents, icons, and folders) accepts such actions and interprets them in a manner consistent with the action’s meaning.

Want To Know More?

Acknowledgments

Thanks to Tony Hill from the Thomson Corporation for reviewing this pattern and providing some great insights into REST.

RPC Service

⊙⊙⊙ Delegate, Facade, Procedure, Proxy, Remote, Remoting, RPC, SOAP, WSDL

RPC Service
Figure 9-2. RPC Service

Developer Story

Dave’s finished coding the backend services for some blogging software. There’s an ArticleRepository object, for example, with functions to create, remove, update, and delete articles. Using a new product, he’s able to effortlessly expose ArticleRepository as a web service API, with a different URL for each operation. Now he can code up the browser script for his own application to talk to the API, and there’s a ready-made API available to third parties too.

Problem

How do you expose services on the Web?

Forces

Refer to the section "Forces" in RESTful Service.

Solution

Expose web services as Remote Procedural Calls (RPCs). Like REST, RPC is a broad term. It’s somewhat ambiguous too, meaning different things to different people. This pattern uses a fairly general definition—a Remote Procedural Call (RPC) is a form of communication where the client invokes a remote procedure on the server. The definition implies:

  • RPCs are generally characterized as actions. The URL is usually verb-like; e.g., /game/createGame?gameId=995 or /game/updater?command=createGame&gameId=995.

  • Typically, though not necessarily, the remoting is designed to be relatively transparent. The server’s backend is developed, and a remoting framework acts as a bridge between client and server, allowing the client to directly invoke backend operations. Often, the remoting framework is distributed across both tiers, wrapping and unwrapping messages at each end.

Here are some concrete forms of RPC:

Procedure-style API

In the simplest case, it’s just a matter of the URL style: the server exposes URLs that look like verbs and invite action, though they don’t necessarily have any direct relationship to the backend technology.

XML-RPC

XML-RPC is a simple protocol for RPCs, using tags like <methodCall>, <methodName>, and <params>. An XML document is uploaded to make the call, and another document is returned with the response. There are many frameworks available to automatically expose backend services as XML-RPC and to invoke such services, so the remoting is fairly transparent from the developer’s perspective.

SOAP

SOAP is based on exposing selected backend operations as HTTP-based services that can be accessed by certain clients. It’s similar to XML-RPC, but offers a whole slew of additional functionality, such as custom data types and asynchronous messaging. The protocol is intended to automatic translation of SOAP calls to and from calls in the native languages being used. For instance, Enterprise Java Beans can automatically be exposed as web services using fancy code generators or mediating proxies. Unfortunately, the complexity of SOAP comes at a cost, and using it can sometimes feel like driving in a nail with a two-ton sledgehammer; some jaded developers have wondered whether SOAP is more about selling consulting services and toolkits than actually making life any easier.

Ajax Stub frameworks

These frameworks are an all-in-one package. XML-RPC and SOAP might automatically generate a web service for you, but you still have to invoke it yourself from an Ajax App. In contrast, Ajax Stub (see later in this chapter) frameworks such as SAJAX (http://modernmethod.com/sajax) create JavaScript wrappers for server-side operations as well as exposing them in the first place. The JavaScript code doesn’t have to issue XMLHttpRequest Calls directly or even with an XMLHttpRequest wrapper. It instead calls a generic remoting function, capable of invoking operations on the backend. See the Refactoring Illustration in the section Ajax Stub, later in this chapter, for an example. The downside is that Ajax Stubs tend not to be fussed about exposing a clean API, because it’s assumed the programmer will never need to look at how the server’s invoked. Consequently, if a third party needs to use it, the API will quite possibly be uglier than an auto-generated XML-RPC or SOAP API.

Can RPC be RESTful? Some argue it can. RESTful Service is one of the largest patterns in this language, precisely because REST is a broad idea consisting of many principles and conventions. Given that RPC URLs represent actions rather than resources, it’s a little over the top to say that RPC can be made truly RESTful. However, many of the REST principles do make sense in an RPC context, and it’s advisable to follow them. Remember that many entities on the Internet, such as caches, are based on certain RESTful assumptions, and you’ll be affected by those no matter how you design your interface. A few guidelines:

  • Read-only queries should be made as GET requests, meaning that you shouldn’t pass a query in the body.

  • Anything that changes server state should be made with POST, including the command and arguments in the body. The command will already indicate the type of action that’s occurring, so there’s probably no need to use other HTTP methods such as PUT or DELETE.

  • Stateful conversation is best avoided. Calls should pass in all the information they need explicitly. Session and cookies should not determine how the server responds to queries; if used at all, they should only be used for authentication.

Real-World Examples

Kiko

Kiko (http://kiko.com) is an online calendar application with a slew of Ajax features. The browser communicates to an interface using RPC-style URLs. For example, the following call retrieves my contacts:

  http://www.kiko.com/kiko/kikoservlet?function=SelectContactsByUser , false ,
  undefined , undefined)

A change is made in the same way. Here’s what the browser called when I added an appointment:

  http://www.kiko.com/kiko/kikoservlet?function=CreateAppt&starttime=2005-9-12 18:0:
  00&endtime=2005-9-12 s18:30:00 , false , undefined , undefined)

Kiko invokes these URLs using POSTs, where the body is just an authentication key. Note that the service could be more REST-like, while retaining the RPC-style URLs, if Kiko wants to open the API to the public and ensure scaleability. To make it more REST-like, queries like SelectContactsByUser would be issued as GETs, with cookies used for authentication in place of the authentication key in the body. This would not only improve consistency across APIs, but also have the direct practical benefit of supporting caching, since GET responses can easily be cached. Also, POSTs could include all arguments inside the body, while retaining RPC-style URLs like /?function=CreateAppt.

Flickr API

The Flickr API (http://www.flickr.com/services/api/), available to external developers, is a good example of an API with RPC-style URLs that also respects the basic REST conventions of GET strictly for reads and POST strictly for writes. Most calls include an API key, which the developer must apply for. A query for photo details such as owner and description is a GET call to a URL like this:

    http://www.flickr.com/services/rest/?method=flickr.photos.getInfo&api_
         key=ap1000&photo_id=2000

You can also effect changes with the API. For example, you can tag an element by POSTing to a URL like this:

    http://www.flickr.com/services/rest/?method=flickr.photos.addTags

containing a body like this:

    api_key=ap1000&photo_id=2000&tags=Screenshot

Code Example: AjaxPatterns RPC Shop Demo

The Basic Ajax Shop Demo (http://ajaxify.com/run/shop) 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 provide a cohesive RPC service. You can contrast this to the Refactoring Illustration in RESTful Service.

A single service acts as a Facade (Gamma et al., 1995) to all server-side functionality. It accepts command-like URLs and routes them to the appropriate function. Read-only queries are of the following form, with the argument being optional:

  services.phtml?command=queryType&someArg=someValue

State-affecting commands instead require all arguments, including the command, to be posted to a simple URL:

  services.phtml

Because the URL is generic, the command must qualify what object it applies to; e.g., addToCart as opposed to add.

Reading the Categories list

To read the Categories, you GET http://ajaxify.com/shop/rpc/services.phtml?command=get-Categories.

Reading an individual category

To drill down to an individual category, say “Movies,” you GET http://ajaxify.com/shop/rpc/services.phtml?categoryName=Movies.

Reading cart contents

To read cart contents, you GET http://ajaxify.com/shop/rpc/services.phtml?command=getCar t. Note that cart access is based on the session, as with the Basic Shop Demo (and unlike the RESTful Service demo). It doesn’t have to be like this, but doing so allowed for a minimal change.

Changing cart contents

To clear the cart, we POST a body of command=clearCart to services.phtml. To add an item, we POST the command and item in the body, such as command=addToCart&item=Accidental Empires to services.phtml.

Alternatives

RESTful Service

RESTful Service (see earlier in this chapter) is an alternative to RPC Service, but many tenets of REST can, and should, still be followed in RPC. See the RESTful Service "Solution" for a comparison.

Related Patterns

Ajax Stub

Ajax Stub (see later in this chapter) automates the production of RPC Services.

Plain-Text Message, XML Message

RPC is often used to design an application-independent web service API, or at least one that doesn’t know anything about the user interface. That being the case, responses tend to be of a raw, semantic nature such as a Plain-Text Message (see later in this chapter) or an XML Message (see later).

Metaphor

Task-oriented user interfaces, such as simple menu systems and the new MS Office Task Ribbon idea, are similar to RPC. They explicitly offer the typical tasks you wish to achieve.

Ajax Stub

⊙⊙ Delegate, Facade, Procedure, Proxy, Remote, Remoting, RPC

Ajax Stub
Figure 9-3. Ajax Stub

Developer Story

Devi begins working on the browser script for a trading application and soon decides she needs a way to execute a trade. There’s already a method to do that on the backend TradeManager object, so after 15 seconds reconfiguring the Ajax Stub, the browser script is able to invoke the method.

Problem

How do you implement an RPC Service (see earlier in this chapter)?

Forces

  • Some services have to reside on the server, for reasons of security, complexity, and performance. Thus, you need to expose web services to be accessed from the browser script.

  • A web service should encapsulate only web-related logic and delegate any business and application logic to the backend.

  • This creates a redundancy: the web service and the backend logic are tied together. When one changes, the other must change, leading to more work and the risk that you’ll forget to change one or the other.

  • The browser needs to access web services via XMLHttpRequest over HTTP, which is fundamentally different to the way both JavaScript and server-side scripts work. It’s tedious to wrap and unwrap messages into a form suitable for transfer.

Solution

Use an Ajax Stub framework that allows browser scripts to directly invoke server-side operations, without having to worry about the details of XMLHttpRequest and HTTP transfer.. The aim is to let the JavaScript call remote operations as if they were regular JavaScript functions, facilitating a more natural program style.

There are several frameworks to support stubbing of this nature. Typically, you declare which backend operations should be exposed, and the framework takes care of the remoting. It will provide a JavaScript stub object that will delegate the call over to the server side. For example, you might have a Java method like this:

  public class Book {
    public String getEdition(int year) {...}
    ...
  }

After configuring an Ajax Stub framework for handling remoting, it’s light work to make call the class from within the browser:

  editionLabel.innerHTML = book.getEdition( );

Typical facilities include:

  • Ability to convert JavaScript arguments and return values into server-side language constructs

  • Sensible handling of server-side errors and exceptions

  • Support for general XMLHttpRequest issues, such as timeouts

A stubbing framework usually consists of two components:

  • A JavaScript component marshalls the call into an XMLHttpRequest, handles the call, and later unmarshalls the response.

  • A server-side configuration component, with some configuration, that accepts the call, delegates to the backend operation, and marshalls the return value into a suitable response.

Decisions

How will you secure the server-side function?

With great power comes great responsibility. An Ajax Stub makes it easy, bordering on trivial, to directly expose business operations. That means it’s also easy to let curious users do things they shouldn’t. Since many Ajax Apps push the whole user interface out to the browser, the web tier is left publishing business methods. Harry Fuecks, author of the Ajax Stub toolkit JPSpan (http://jpspan.sourceforge.net/), gave this cautionary example on the Ajax Blog (http://ajaxblog.com/archives/2005/05/25/a-grumpier-ajaxian). A naïve export of a business operation could end up with a call like this:

  var ccNum = AJAX.getCreditCardNumber(userId);

Anyone can edit the JavaScript and pass any argument to the credit card operation. Another stubbing framework, DWR (http://getahead.ltd.uk/dwr/getstarted), warns: “There is a danger that you could cause all sorts of security problems using this code. You need to think about security earlier rather than later.”

Other approaches, such as RESTful Service, are also vulnerable to the same threat, but they tend to encourage more analysis, because you have to explicitly design the service interface. With Ajax Stub, you’re effectively ticking a few boxes to say which backend operations can be executed.

A few guidelines:

  • Even though you can publish an interface very quickly, that doesn’t mean you should. Do take the time to consider the implications of making an operation available to the public (or whatever user base will be using your Ajax App), who will be able to call it with whatever arguments they please.

  • The framework’s module is exposed as a web service—your environment might be able to control access to particular services. For example, the DWR Framework for Java stubbing (http://getahead.ltd.uk/dwr/security) notes: “DWR allows you to grant access using two J2EE based mechanisms. Firstly you can define access to dwr based on J2EE roles. Secondly within DWR you can define access to methods on a role basis.”

  • Depending on the environment, the backend operation may need to use some form of authentication. In some cases, the operation will have direct access to request information such as the URL and cookies, which will facilitate authentication. The downside is that you’ve begun to incorporate web-related concepts into the business logic, which is what Ajax Stubs seek to avoid.

  • Be wary of the framework as well. One Ajax Stub framework, CPAINT (http://cpaint.sourceforge.net/), caused some security alerts due to the possibility of malicious code being executed on the server (http://secunia.com/advisories/16454/). The team was quick to respond, and the Ajax Stub pattern is not inherently flawed, as some people had assumed. However, it’s important to understand just what exactly the Ajax Stub framework is doing.

Real-World Examples

These examples cover available frameworks for creating Ajax Stubs.

SAJAX framework

SAJAX (http://www.modernmethod.com/sajax/) is an Ajax Stub framework that actually supports multiple backend languages. The browser side is the same for all, but there are different server-side proxy components depending on which language is used. Among the backend languages are ASP, ColdFusion, Perl, PHP, Python, and Ruby.

DWR framework

DWR (http://getahead.ltd.uk/dwr/overview/dwr) is an open source framework for Ajax Stubs to Java classes. On the server side, you run a DWR servlet and configure it with a separate XML file. In the browser, just include a JavaScript file. Java and JavaScript may not have much in common, but calls do at least look the same. A DWR JavaScript-to-Java call looks just like a Java-to-Java call.

CL-AJAX framework

Richard Newman’s open source CL-AJAX (http://www.cliki.net/cl-ajax) supports stubbing of Common Lisp functions.

Code Refactoring: AjaxPatterns SAJAX Sum

In this refactoring illustration, the Basic Sum Demo (http://ajaxify.com/run/sum) is refactored to use an Ajax Stub (http://ajaxify.com/run/sum/stub), based on SAJAX (http://www.modernmethod.com/sajax/). To begin with, we do away with the old Sum service (sum.phtml) and create a standalone, backend, calculator module. Now that we’re using an RPC approach, we’ll call the operation add instead of sum, to make it distinctly a verb. So calculator.phtml looks like this:

  <?
    function add($figure1, $figure2, $figure3) {
      echo $figure1 + $figure2 + $figure3;
    }
  ?>

With the stub, we can allow the browser-side script to directly invoke that function. The JavaScript call looks like this:

  function submitSum( ) {
    x_add($("figure1").value,$("figure2").value,$("figure3").value,onSumResponse);
  }

Here’s how you set up the SAJAX glue between the JavaScript x_add and the PHP add. In PHP, we tell SAJAX which functions are exported:

  <? require_once("Sajax.php"); ?>
    ...
    sajax_init( );
    sajax_export("add");
    sajax_handle_client_request( );

And in outputting the script, some PHP code generates the required JavaScript—in this case, the x_add( ) function, which will forward on to SAJAX on the server side and eventually interpret its response:

  <script>
    <?
      sajax_show_javascript( );
    ?>
  </script>

Alternatives

XMLHttpRequest Call

Ajax Stubs are built on top of XMLHttpRequest Calls (Chapter 6) and represent a different approach to the usual Ajax remoting. XMLHttpRequest Calls leave the user to deal directly with HTTP concepts and packing and unpacking of messages, tasks that Ajax Stubs take care of. The benefit of direct XMLHttpRequest Calls is that the server-side service interface is independent of the underlying implementation.

XML-RPC and SOAP

XML-RPC and SOAP are more generic (non-Ajax-specific) ways to develop RPC Services (see earlier in this chapter). Since Ajax Stubs tend to produce Ajax-specific services, XML-RPC or SOAP might be more appropriate if you’re opening up to external clients.

Related Patterns

RPC Service

An Ajax Stub is one way to implement an RPC Service.

JSON Message

JSON Messages (see later in this chapter) are being used by several Ajax Stub frameworks because Ajax Stubs need to share data between browser and server; i.e., inbound arguments and outbound return values. These objects should be standard JavaScript objects in the browser and standard Java or PHP or whatever-your-language-choice objects on the server. In between, it’s most convenient to transfer them as strings. JSON defines a standard way to convert objects in many languages to and from a string representation.

An even more ambitious standard is JSON-RPC (http://json-rpc.org/), a protocol for remoting that’s touted as a lightweight alternative to XML-RPC. There’s an Ajax Stub framework based on JSON-RPC, the aptly named JSON-RPC-Java (http://oss.metaparadigm.com/jsonrpc/).

HTML Message

⊙⊙⊙ AHAH, Direct, Display, HTML, InnerHTML, Message, Precise, ServerSide, Visual

HTML Message
Figure 9-4. HTML Message

Developer Story

Dave’s identified the need for a credit history service, providing a list of transactions. JavaScript resources are limited, so the entire HTML is created server side, and the browser application has only to morph a DOM element with the entire HTML response.

Problem

What format should be used for server responses?

Forces

  • The browser display needs to be dynamic in Ajax Apps.

  • The display changes by altering the DOM, and HTML is often used to specify the new value.

  • The nature of the change is often complex and needs to be determined server side.

  • Not all developers know JavaScript, and many feel its usage is best minimized.

Solution

Have the server generate HTML snippets to be displayed in the browser. In this approach to browser-server dialogue, the server-side service outputs some HTML, which is picked up by the XMLHttpRequest callback function and an element then morphed by setting its innerHTML property to the response HTML. In general, the server side is application-specific because the HTML response is closely tied to the application’s display style.

The XMLHttpRequest allows callers to retrieve responses as either XML or plain-text. With HTML, it’s usually easiest to retrieve it as a plain-text string. If the HTML is a pure XHTML document, XML is also an option, but usually that’s not the case because there’s no need for a header section. The entire response can be as simple as "<strong>You Win!</strong>". That’s not an XHTML document because there’s no <xml> tag, nor are there HTML header and body sections.

HTML Messages should be used with caution because they couple server-side services with browser display. That means it’s difficult to develop the tiers in parallel. In maintenance, if you change the display by altering its initial HTML or any JavaScript manipulation, you often need to change the HTML-generating service too. There’s also a risk on the server side that you might be coupling business logic with HTML generation. So when might an HTML Message be appropriate?

Performance

Since browser-side parsing and rendering can be expensive, HTML Messages can make an application more responsive, especially if the HTML is cached on the server or the browser.

Server-Side Code Generation

One case where HTML Messages make some sense is with Server-Side Code Generation (Chapter 12), where the server builds all the browser-side code for you. There are strengths and weaknesses of such frameworks, and if you decide to use one, then browser-server coupling is not really an issue because all maintained code is server side anyway.

Legacy Code

Most legacy applications will use the conventional approach of publishing pages from the server. They therefore already have all the HTML generation present in the server-side environment, so if you’re Ajaxifying a legacy application, a quick migration path is to retain the server-side HTML generation where possible.

Complex HTML

In the rare case that your HTML or JavaScript is particularly complex, you might prefer to generate it all on the server side, where development and debugging is sometimes easier.

Graceful Degradation

When there’s a chance users won’t have a recent browsers, HTML Messages allow you to encapsulate more logic in the server. Of course, if JavaScript is not enabled at all, the “messages” will have to be full pages.

Server-Centric Attitude

If you’re concerned about keeping as much logic as possible in the one language and environment, or you’d prefer not to work much with JavaScript, HTML Messages are more appropriate.

Typically, HTML Messages rely on a block-level element existing in the DOM, often a div or form. The HTML Message will contain a specification for the entire contents of the element. Some of the XMLHttpRequest wrapper libraries, such as JAH/AHAH (http://microformats.org/wiki/rest/ahah) and Sack (http://twilightuniverse.com/2005/05/sack-of-ajax/), support HTML Messages by letting the caller directly state a DOM element as the callback destination instead of the usual callback function. When the response returns, the DOM element is automatically morphed with the service’s response.

A variant of this pattern is Behavior Message; see On-Demand JavaScript (Chapter 6). Also, note that HTML Messages almost flow from server to browser; you’d rarely need to upload an HTML Message back to the server.

Decisions

At what level of granularity will the HTML apply?

In the extreme, the service could generate HTML for the entire document, making it similar to a conventional page refresh. In practice, you’ll usually want to limit the HTML’s level of granularity to well-defined, distinct page elements. For example:

  • An account status

  • A form

  • A menu

How much style will be contained in the message?

You’ll need to decide how much style is contained in the message. An HTML Message already ties the server to the browser somewhat, but style directives will tie it further to the server. In general, it’s good practice to just include class names and element IDs so that the browser application can influence the style, usually with a standard CSS stylesheet. If you do this, you’ll need to ensure the names are unique, and you’ll need to decide on exactly which elements need to be given ID and class declarations.

Real-World Examples

Digg Spy

Digg Spy (http://digg.com/spy) shows new stories and events such as user moderation as they happen (see Figure 5-5). The XMLHttpRequest Call (Chapter 6) accesses a static URL (http://digg.com/last10) containing the last 10 submissions and integrates them into the page. The HTML looks like this:

  <div class="news-body" id="main64115">
    <h3 id="title">
      <a href="http://digg.com/movies/How_LEGOs_Are_Made_"> How LEGOs Are Made!
</a>
    </h3>
    <p class="news-submitted">
      <a href="/users/Akshun"><img src="/img/user-small/user-default.png" alt=
"Akshun" height="16" width="16"> </a>
    submitted by <a href="/users/Akshun"> Akshun </a> 14 hours 22 minutes ago
      (<a href="http://www.popandco.com/archive/moab/" class="simple tight" title=
"How LEGOs Are Made!"> ... </a>) </p>
  <p> </p>
  </div>
  <div class="news-body" id="main64550">
  ...

Rapha

Rapha (http://www.rapha.cc) is an e-commerce web site for cycling gear (Figure 9-5). The shopping cart is Ajaxian, requiring no page refresh to update. Each time an item is purchased, the HTML for the shopping cart is retrieved. For example:

  <div id="basket">
    <h3>Your basket:</h3>
    <ul>
      <li>Small Softshell Jacket x 2</li>
    </ul>
    <p><a href="/basket/">Edit selection</a> | <a href=
"/checkout/">Go to checkout</a></p>
  </div>
Rapha
Figure 9-5. Rapha

Amazon Zuggest

Francis Shanahan’s Amazon Zuggest (http://www.francisshanahan.com/zuggest.aspx) provides a Live Search: results are shown as you type. The server responds by providing the entire HTML for each result—for example:

  <table>
    <tr><td valign=top width='20%'><b>Vempire Or Dark Faerytales
in Phallustei</b><br>
    <a href='http://www.amazon.com/exec/obidos/redirect?tag=francshanacom-20%26link_
code=sp1%26camp=2025%26creative=165953%26path=http://www.amazon.com/gp/
redirect.html%253fASIN=B0000525ZY%2526tag=francshanacom-20%2526lcode=sp1%2526cID=
2025%2526ccmID=165953%2526location=/o/ASIN/B0000525ZY%25253FSubscriptionId=
16KBB0XN5XP4WSNNVKG2'
target=_blank>Click to View</a><br>
    [Music]<br>List Price<span class='lp'>$23.99</span><br>
    <span class='lnp'>1 NEW from $14.99[$13.50 used]</span>
    ...
  </td></tr><table>

TalkDigger

TalkDigger (http://talkdigger.com) is a webfeed meta-search. Enter a query, and it fires off parallel queries to different search engines (an example of Multi-Stage Download). Each result is returned as an HTML table to be added to the page.

Code Example: Digg Spy

Digg Spy (http://digg.com/spy) responds with the full HTML to be displayed as well as some meta-content at the end. The results are fetched periodically—filldigs( ) is triggered by the recurring lastdigs( ). filldigs( ) executes an XMLHttpRequest Call, extracts the HTML from the full response, and morphs the results panel using its innerHTML property:

  function startlastdigs( ) {
    window.setInterval("lastdigs( )",15000);
  }
  function filldigs( ) {
    ...
    s.open("GET",url2,true);
    s.onreadystatechange=function( ) {
        if (s.readyState == 4) {
        ...
        b = responsestring2.split(split);
        ...
        document.getElementById('diggspy').innerHTML = b[0];
        ...
      }
    }
    ...
  }

Alternatives

Plain-Text Message, XML Message, JSON Message

Plain-Text Message, XML Message, and JSON Message (see more on these later in this chapter) all involve sending raw data as opposed to concrete display detail. When the browser receives such responses, it can render it or use it in some other way, such as retaining some information. In contrast, HTML Messages are likely to be display directly and are not retained. A further difference is that HTML Messages tend to be responses only, whereas these other formats are often used for uploading data as well.

Related Patterns

On-Demand JavaScript

Where HTML Message provides snippets of HTML to be fused on to the page, On-Demand JavaScript (Chapter 6) can provide snippets of JavaScript to be executed immediately. The idea is introduced in that pattern as “Behavior Message.”

Metaphor

Sending an HTML Message is like sending a photograph—there’s a lot of visual detail, but any metadata, such as location and subjects, can only be inferred.

Plain-Text Message

⊙⊙ Acknowlegement, Custom, PlainText, Semantic, String

Plain-Text Message
Figure 9-6. Plain-Text Message

Developer Story

Devi’s working on an auto-completion form field. Every few seconds, the server needs to respond with a list of suggestions. Devi codes the server side to output the suggestions as a comma-separated list, as it’s convenient to output on the server and easy to parse in the browser.

Problem

How can you transfer data between server and browser?

Forces

  • Ajax Apps require messages to be transmitted back and forth.

  • Both browser and the server must be able to access the message. That usually means the format must be easily accessed in JavaScript as well as in whichever server-side language is used.

Solution

Pass simple messages between server and browser in plain-text format. This is a broad pattern, because “plain-text” is an ambiguous term. The emphasis here is on keeping things simple—XML or JSON are often more appropriate for complex data structures, but can also add unnecessary complexity.

Despite the name, XMLHttpRequest is perfectly capable of working with plain-text responses. As discussed in XMLHttpRequest Call (Chapter 6) and XML Message (later), the browser script can decide how to interpret the response in XMLHttpRequest by switching between the responseText and responseXML properties.

Plain-text formats include:

Response Code

Sometimes, all that’s required is a simple response code, such as a numeric ID or a text message such as “OK” or “Failed.” Note that, in this case, an appropriate HTTP Response Code codes may be more standards-based and in line with RESTful Service conventions.

A simple text string

For example, a user’s name.

A list

For example, a comma-separated list of search results.

A custom data format

For example, a list of strings, where each string is a comma-separated list of object attributes.

While browser support for XML is reasonably good, especially with third-party libraries, it’s also quite easy to manipulate arbitrary text formats. JavaScript provides a standard string manipulation library, including the particularly helpful regular expression and grouping facilities.

The case for plain-text is particularly compelling in the following situations:

Simpler messages

The simpler the message, the more compelling the argument for plain-text messages. Once the string starts to get more complex, there’s a better argument for relying on XML support from the browser and third-party libraries.

External clients

XML is often a better choice when it’s not just the web app that’s using the service. That’s partly for reasons of convention—XML is simply a standard transfer format on the Internet. But there’s also a more technical reason: using DTDs or XML Schemas, you can specify the format in an unambiguous manner that can be enforced whenever a document is encountered.

Skill base

XML may be a standard, but that’s useful only if people know the standard. The better developers are with XML technologies in both the browser and the server, the more compelling the argument for XML.

Real-World Examples

Lace Chat

Brett Stimmerman’s Lace Chat (http://www.socket7.net/lace/) is an Ajax chat app (Figure 9-7). When the page is initially shown, all user messages are downloaded as a single, long string. Within the string, each user message is captured as a set of attributes, separated by pipe characters:

  1135646360:749||||date-1135646204||*Monday, 26 December
  2005||||hour-17||*17:00||||1135646204||Posted about 3 minutes ago at
  17:16||Aj Two||Yeah you can *SO* chat in real time||||1135646212||Posted
  about 2 minutes, 52 seconds ago at 17:16||*Lace||AJ One
  has joined the conversation||||1135646212||
Lace Chat
Figure 9-7. Lace Chat

Magnetic Poetry

In Magnetic Poetry (http://www.broken-notebook.com/magnetic/), you drag tiles around a workspace. When the browser receives an updated position, the message looks like a structured command statement:

  Update magnetic_poetry set top_value=291, left_value=119 WHERE id=81

HousingMaps

HousingMaps (http://housingmaps.com) is a mashup between Google Maps and Craigslist (http://craigslist.com), a community-oriented classified advertising web site. The HousingMaps portion is downloaded with an XMLHttpRequest Call that retrieves the 15 or so results matching a query. Each result represents a single home and is broken into a sequence of attributes, one line at a time, and prefixed with an identifier:

  PA:34.0917
  PN:-118.28
  IC:p
  DS:One Bath With Small Loft Duplex Near Sunset Junction
  AD:Hyperion Ave &&& Sunset Blvd</line><line>
Los Angeles</line><line>CA
  ...
  I4:a.im.craigslist.org/rR/iv/X1dT18TzV07cfjuQzouhKQ5EETuK.jpg
  LC:1071999
  PA:34.0763
  PN:-118.294
  IC:p
  DS:1930&&#39;s Restored Spanish Beauty- 1St Month Free
  AD:Berendo &&& Beverly</line><line>
Los Angeles</line><line>CA
  ...
  I4:a.im.craigslist.org/n0/Xm/SS3hSoIWLOsc8wOjaiLGQK5HFbzl.jpg
  LC:1072004
  ...

Code Example: Lace Chat

The response in Lace Chat is a list of attributes, separated by pipe characters. Each complete record is separated by ||||, and each attribute within a record is separated by a smaller string, ||. The handling code first splits the string into an array of records, then splits out the attributes within each record:

  // Records are separated by four pipes ||||
  var results = this.httpGetObj.responseText.split('||||');
  ...
  for (var i = 1; i < results.length; i++) {
    var first;
    // Fields are separated by two pipes ||
    var fields = results[i].split('||');
    ...
    var timeStr = fields[1];
    var textStr = fields[3];
    ...
    p.setAttribute('id', 'msg_' + fields[0]);
    ...
  }

Alternatives

XML Message

As discussed in the "Solution,” an XML Message may be a better alternative for more complex data.

XML Message

⊙⊙⊙ Document, Format, Hierarchical, PlainOldXML, POX, Semantic, Structured, XML

XML Message
Figure 9-8. XML Message

Devloper Story

Dave is creating an Ajax search engine. The results are offered as a RESTful Service, so that external developers can create their own interface. The results are presented as XML, and Dave’s own search interface pulls it down with an XMLHttpRequest call, then transforms the result to HTML.

Problem

How can you transfer data between server and browser?

Forces

  • Ajax Apps require messages to be transmitted back and forth.

  • Both browser and the server must be able to access the message. That usually means the format must be easily accessed in JavaScript as well as whichever server-side language is used.

Solution

Pass messages between server and browser in Extensible Markup Language (XML) format. It’s feasible to pass XML in both directions. On the server side, it’s a common way to expose structured data as text, and browser-side applications can download XML with an XMLHttpRequest Call and parse it in different ways. Where the browser needs to upload some complex data, it’s fairly easy to serialize the data as XML and upload it in the body of an XMLHttpRequest Call.

XML is the definitive standard for data transfer across the industry, so just about any server-side development language has comprehensive support. The great advantage of XML over custom formats is the massive base of supporting frameworks, libraries, editors, and general tools. How you deal with XML on the server is language-specific, and a few choices are outlined in "Decisions,” next. However you do it, make sure the server presents XML content with the appropriate header to ensure its handled correctly by XMLHttpRequest:

  Content-type: text/xml

As the name implies, XMLHttpRequest was developed with XML transfer in mind. To retrieve an object with an XMLHttpRequest, first point it to a URL known to serve XML:

  xReq.open("GET","http://ajaxify.com/run/portal/drilldown/drilldown.phtml
                    ?categoryName=Overviews",true);

When XMLHttpRequest delivers a response, the response can either be interpreted as a DOM object or plain-text:

  var domObject = xReq.responseXML
  alert(domObject) // Outputs "[Object]" (IE)
                   // or "[object XML Document]" (Firefox)
  var xmlString = xReq.responsetText
  alert(domObject) // Outputs the whole string
                   // i.e. "<category ...> ... </category>"

In most cases, you want to use responseXML because it gives you a well-structured DOM object: a hierarchical structure that can be navigated using industry-standard conventions. With recent browsers, you can rely on some basic parsing functionality to interrogate DOM objects. HowToCreate has a good list of DOM traversal functions (http://www.howtocreate.co.uk/tutorials/texterise.php?dom=1) and many of the Ajax Patterns demos perform such parsing (e.g., the Basic Wiki Demo; see http://ajaxify.com/run/wiki).

If you’re parsing XML, consider delegating to a cross-browser library. Sarissa (http://sarissa.sourceforge.net), for example, has a variety of cross-browser XML manipulation routines. Another library, Interactive Website Framework (IWF) (http://sourceforge.net/projects/iwf/), simplifies XML expressions. Instead of the following standard DOM query:

  var node = doc.documentElement.firstChild.firstChild.getAttribute("size");

you can write this:

  var node = doc.groceries.frozen[0].pizza[0].size;

With a DOM object representing server data, the receiver can do one or more things:

  • Transform the XML into some HTML. (See "Decisions,” next.)

  • Interrogate it to decide what to do next.

  • Store it for later use in an XML Data Island.

  • Modify it based on client state and upload it again.

This discussion has mostly focused on downloading XML from server to browser. That’s the most common direction, but XML can also flow upwards too. It’s sometimes easier to upload complex data as an XML document than as a set of CGI-style variables. To do this with XMLHttpRequest, you simply pass in the whole XML string as the argument to send( ). You’ll also need to ensure the transport type is suitable—typically, POST (or PUT).

  xReq.send(xmlString);

The XML string being sent usually represents browser state or user input. Most often, it’s simply built up with some manual coding, appending strings together and including variables where appropriate. However, you can also use a library like Sarissa or Anders Noras’s XmlSerializer (http://dotnetjunkies.com/WebLog/user/Profile.aspx?UserID=1095) to convert from a DOM object—or some other object—into an XML string.

Finally, a note of caution. “XML” is the X in “AJAX,” so it’s sometimes considered a core Ajax technology. And its association with XMLHttpRequest also strengthens the argument for XML Messages. However, don’t let all this make you feel obligated to use XML Messages. XMLHttpRequest supports transfers in any plain-text format, and it’s fine to use Plain-Text Messages in many situations. XML is relatively simple, and there’s good browser support, but sometimes it just doesn’t fit the bill. The "Solution" for Plain-Text Message compares the two approaches in more detail.

Decisions

How will the server generate XML?

There are many ways the server might generate XML messages:

  • By using custom code that hand-creates the XML string.

  • By building up a DOM object and serializing it.

  • By using a generic framework to convert standard data structures into XML.

  • By retrieving existing XML documents from the filesystem or external sources.

Will you specify a DTD or Schema?

When you pass XML Messages back and forth, each end must assume the same document format. That’s a standard requirement with XML, and you can define the format precisely using a separate document: either a Document Type Definition or a stricter XML Schema document.

When the browser needs to render the message, how it will transform the XML?

The browser doesn’t always need to render incoming XML messages—sometimes it just uses the data. But, for situations when it does render the XML, there are a few options. In all cases, the script is building up some HTML, which will then be injected onto a DOM element by setting its innerHMTL property to the HTML string.

Manual JavaScript Conversion

For simple messages, you might find it easier to just perform a little parsing and manually create an HTML string.

XSLT

If you have the skill base and a suitable framework for the browsers you’re targeting, Browser-Side XSLT allows for powerful conversion of XML.

Templating

Sometimes, Browser-Side Templating is a happy medium between the above two approaches. You still have to parse the XML document somehow, but the HTML generation is more straightforward.

Real-World Examples

Netflix Top 100

When you roll over a movie title in the Netflix Top 100 (http://www.netflix.com/Top100#), a balloon soon appears with summary details (Figure 9-9). After the rollover, an XMLHttpRequest Call occurs, which receives movie details like this:

  <MOVIES>
  <MOVIE ID="60031236" POS="17" DS="0">
    <TITLE>Kill Bill: Vol. 2</TITLE>
    <SYNOPSIS>In this film noir tale written ... </SYNOPSIS>
    <DETAILS RATED="R" RELYEAR="2003" GENREID="296" GENRENAME="Action &&&
Adventure"/>
    <STARRING>
      <PERSON ID="92495" NAME="Uma Thurman"/>
      <PERSON ID="20008295" NAME="Lucy Liu"/>
    </STARRING>
    <DIRECTOR>
      <PERSON ID="20001496" NAME="Quentin Tarantino"/>
    </DIRECTOR>
  </MOVIE>
  </MOVIES>
Netflix
Figure 9-9. Netflix

Protopage

Protopage (http://protopage.com) is a portal-style application with excellent personalization capabilities. Each time you change something on the page, a command is uploaded to the server via an XMLHttpRequest Call. For example, here’s what the browser sent when I moved a Portlet around:

<command accountId="25570" protopageId="25568" protopagePath="mahemoff" name=
"save-panel-geometry">
  <param name="id">129644</param>
  <param name="left">216</param>
  <param name="top">476</param>
  <param name="width">423</param>
  <param name="height">71</param>
  <param name="collapsed">false</param>
  <param name="zIndex">33</param>
  <param name="verticalScrollProportion">0</param>
</command>

Google Maps

Google Maps is perhaps the most famous usage of XML Messages. Meta-information is downloaded as XML and rendered with Browser-Side XSLT.

Code Refactoring: AjaxPatterns XML Sum

The Basic Sum Demo (http://ajaxify.com/run/sum) uses a Plain-Text Message to transfer the sum result from server to browser. So if the browser sends a GET query requesting the sum of 4 and 8, the entire response is “12.” That works fine, but sometimes we’d like a response to contain the original query too—it’s convenient for caching, for instance (see Browser-Side Cache [Chapter 13]). If we’re going to provide the original figures of the sum, the data’s becoming a bit more complex—we now have a list as well as different types of data. To keep the format self-describing, let’s refactor to XML.

The XML Sum Demo (http://ajaxify.com/run/sum/xml) behaves the same as the original version, but the server side returns results like this (http://ajaxify.com/run/sum/xml/sumXML.php?figure1=4&figure2=8&figure3=):

<sum>
  <inputs>
    <figure id="1">4</figure>
    <figure id="2">8</figure>
    <figure id="3"></figure>
  </inputs>
  <outputs>12</outputs>
</sum>

To avoid confusion, the server-side service is now called sumXML.php, and reflecting the new location is the only change required to the browser call. The server-side service has been altered to output the full XML. Note the XML content-type declaration in the header, which is necessary for the XMLHttpRequest Call.

  <?

    header("Content-Type: text/xml");

    $sum = $_GET["figure1"] + $_GET["figure2"] + $_GET["figure3"];

    echo <<< END_OF_FILE
  <sum>
    <inputs>
      <figure id="1">{$_GET["figure1"]}</figure>
      <figure id="2">{$_GET["figure2"]}</figure>
      <figure id="3">{$_GET["figure3"]}</figure>
    </inputs>
    <outputs>$sum</outputs>
  </sum>
  END_OF_FILE

  ?>

In this refactoring, the figures aren’t used, but the sum is still required. The callback function therefore navigates through the response XML Message to obtain the sum figure.

  function onSumResponse(xml, headers, callingContext) {
    var sum = xml.getElementsByTagName("outputs")[0].firstChild.nodeValue;
    self.$("sum").innerHTML = sum;
  }

Alternatives

Plain-Text Message

As mentioned earlier in the "Solution,” XML can often be overkill for simple messages, and Plain-Text Messages (see earlier in this chapter) are worth considering as an alternative.

JSON Message

Just like XML Message, JSON Message is a suitable representation for data of various complexities. The "Alternatives" section of JSON Message compares the two formats.

JSON Message

⊙⊙ JSON, Marshal, Semantic, Serialize, YAML

JSON Message
Figure 9-10. JSON Message

Developer Story

Dave is creating an Ajax calendar. The browser periodically polls for new appointments, which the server is sending as JSON messages. Since JSON messages are just JavaScript code for object creation, Devi’s browser script needs only to run eval against each message in order to reconstruct the appointment.

Problem

How can you transfer data between server and browser?

Forces

  • Ajax Apps require messages to be transmitted back and forth.

  • Both browser and the server must be able to access the message. That usually means the format must be easily accessed in JavaScript as well as whichever server-side language is used.

Solution

Pass messages between server and browser in JavaScript Object Notation (JSON) format. JSON is a standard serialization format, created in 2002 as a cleaner and lighter alternative to XML. As with XML, the object can range in complexity from a simple string to a deep hierarchical structure. Also like XML, JSON is language-neutral, meaning that you could marshall a C++ object into JSON notation and unmarshall it to form an object in Perl. But in practice, JSON is particularly suited to browser-server communication because it’s a format based on JavaScript.

In fact, a JSON Message is JavaScript. This is a valid JSON Message:

  "Homer J."

You can test browser-based JSON conversion on the Basic JSON Demo (http://ajaxify.com/run/json/). As you’ll see there, the JSON Message "Homer J." maps to the JavaScript string, Homer J..

Here’s a more complex example (as on the demo, reformatted):

  {"houseNumber":"742",
    "street":"Evergreen Terrace",
    "city":"Springfield",
    "postcode":"49007",
    "country":"USA",
    "comments": ["Deliveries accepted.","Familiar address, huh?",""]
  }

As you can see, this JSON message is just a JavaScript object literal. You convert it like this:

  var name = eval("(" + nameJSON + ")");

Or like this (http://jibbering.com/2002/4/httprequest.html) if it takes your fancy:

  var name=new Function("return " + nameJSON)( );

Note that you don’t even need a JSON library in the browser. The browser can pick up a JSON string using an XMLHttpRequest Call and simply run the standard eval function.

However, there is actually a JavaScript JSON library (http://www.crockford.com/JSON/js.html), which adds two important capabilities: parse( ) for safer string-to-object conversion, and stringify( ) for object-to-string conversion. The former is an alternative to manual JavaScript evaluation, because evaling arbitrary messages puts your app at risk of running malicious JavaScript code. Thus, the string-to-object conversion should be executed if you don’t trust the message. To parse a string, use the following codee:

  var name = JSON.parse(nameJSON);

If you need to upload something to the server, you’ll need to convert a JavaScript object to JSON with stringify( ). The Basic JSON Demo (http://ajaxlocal/run/json/) shows this conversion process too. The call looks like this:

  var nameJSON = JSON.stringify(name);

So far, the examples have considered only JavaScript conversion. But JSON wouldn’t be very useful if you could only convert to and from JavaScript objects—you need to convert at the other end too, and your server side is probably not written in JavaScript. That’s why there are JSON processors for many languages. Using these processors, you can easily share an object between JavaScript and your favorite server-side language.

A remoting modification (http://ajaxify.com/run/json/remoting) of the Basic JSON Demo (http://ajaxify.com/run/json/) sends JSON to the server, using XMLHttpRequest Calls. There, it’s converted to standard PHP objects using Michael Migurski’s JSON-PHP library (http://mike.teczno.com/json.html). The library works similarly to JSON libraries for Java, .Net, and other languages. The following code converts JSON to a standard object:

  $json = new JSON( );
  $newObject = $json->decode($jsonString);

while the following code performs the reverse operation:

  $json = new JSON( );
  $json = $json->encode($object);

Real-World Examples

Many web sites use JSON as their data transfer format for shuttling data between browser and server.

Kiko

Kiko (http://kiko.com) is an online calendar application with a slew of Ajax features (Figure 9-11). As you’d expect, the server holds a model of the calendar, and the browser keeps uploading changes using XMLHttpRequest Calls. JSON is the message format used for server responses—each response is a list of objects.

Kiko
Figure 9-11. Kiko

Delicious JSON Feed

Delicious (http://del.icio.us/doc/feeds/json/), a social bookmarking tool, provides a Web Service that exposes a user’s recent bookmarks in the form of a JSON Message. For reasons discussed in On-Demand JavaScript (Chapter 6), this means a browser script can conveniently grab the data without the need for a Cross-Domain Proxy.

Route Planning

Jim Ley’s Route Planning application (http://jibbering.com/routeplanner/) shows you all the routes for a given airport (Figure 9-12), and, as his long-running XMLHttpRequest Tutorial (http://jibbering.com/2002/4/httprequest.html) explains, it uses JSON. For example, a JSON Message for the LAX airport is available at http://jibbering.com/routeplanner/route.1?LAX. What the browser receives from the following JSON Message is an XMLHttpRequest Call (... has been substituted for multiple data items):

  {from:'LAX',airports:[{id:"AMS",country:"NL",lat:"52.316666666667",
lon:"4.7833333333333",
tz:"Europe/Amsterdam",name:"Amsterdam",shortname:"Schiphol"},...,{id:"IAD",
country:"US",
lat:"38.95",lon:"-77.45",tz:"America/New_York",name:"Washington, DC",
shortname:"Washington Dulles International"}],routes:[{carrier:"star",toAirport:"AMS",
miles:5570},...,{carrier:"oneworld",toAirport:"DCA",miles:2304}]}
Jibbering Route Planner
Figure 9-12. Jibbering Route Planner

Ajax.Net framework

Ajax.Net (http://ajax.schwarz-interactive.de/) is one of several Ajax Stub frameworks that uses JSON Messages to transfer data, which can easily be converted to and from native objects at either end. For more details, see "JSON Message" in the "Related Patterns" section of Ajax Stub.

Code Example: Kiko

Kiko (http://kiko.com) responds to XMLHttpRequest Call with JSON Messages. When you log in, it downloads a list of appointments like this:

  [
    {"title":"text","isevent":"bool",   "picture":"text","starttime":"timestamp",
"endtime":
"timestamp","recurs":"int2", "recurend":"timestamp","insystem":"timestamp",
"recurstart":
"timestamp",  "recurweek":"int2","description":"text","defaultfree":"bool","location":
"text","apptid":"int8"},{"title":"Roundup meeting","isevent":"t","picture":"",
"starttime":
"2005-09-16 19:00:00","endtime":"2005-09-16 19:30:00","recurs":"1","recurend":"",
"insystem":
"2005-09-12 14:52:10.965713","recurstart":"2005-09-16 04:00:00","recurweek":
"16","description":"Hopefully just a quick roundup","defaultfree":"f","location":
"Cyberspace","apptid":"9222"},    {"title":"Go Home!","isevent":"t","picture":
"","starttime":"2005-09-15 21:00:00","endtime":"2005-09-15 21:30:00","recurs":
"0","recurend":"","insystem":"2005-09-12 15:00:33.659793","recurstart":"","recurweek":
"","description":"","defaultfree":"f","location":"Office, Bar, Home","apptid":"9288"}
  ]

Note that the message format here is a little unusual: everything is Strings, whereas JSON can store booleans and numbers directly. Consequently, the first element of the array includes some metadata to facilitate conversion, and the JavaScript includes a generic function to create native JavaScript objects from JSON messages like this.

Kiko’s browser script also includes some conversion to JSON, as shown below (though I was unable to exercise this code). Typically, requests in Kiko are made as POSTs with CGI-style parameters, and only the responses are JSON.

  var obj=json.stringify({'type':'newuser','email':email})

Alternatives

XML Message

JSON defines itself as a “fat-free alternative to XML.” Before considering the differences between the formats, let’s first look at what they have in common.

  • Both are formats that depict an object as a plain-text string.

  • Being plain-text string formats, both are suitable for transfer across HTTP. This means that both are suitable as inputs and outputs for a Web Service.

  • Each format is supported by libraries in numerous languages, including JavaScript. There are libraries to convert from native objects to either format and back again to native objects.

JSON Message has several advantages over XML Message (see earlier in this chapter):

  • JSON is more compact, and the lack of tags sometimes leads to a better visual representation of the underlying data.

  • It’s often claimed that JSON is faster for browsers to parse, though a recent investigation (http://blogs.ebusiness-apps.com/dave/?p=45) suggests XML parsing does scale better.

  • JSON is a concrete data format. XML, in contrast, is really a meta-format, and a developer has many choices to make about the precise XML dialect to use. Each mapping strategy has its own conventions—for example, developers need to decide on tag names and between tag attributes or nested tags. Consequently, a server-side XML-object mapping framework may not be message-compatible with a JavaScript counterpart. Also, don’t underestimate the amount of meetings and emails that will be necessary to resolve a seemingly trivial argument over data formats. In that sense, JSON is closer to a defined XML dialect than to XML itself.

  • Within the browser, JSON has the edge in terms of support and consistency, since it’s based on standard JavaScript.

  • JSON happens to be quite compatible with YAML (“YAML Ain’t Markup Language”; see http://www.yaml.org/about.html), a similar lightweight alternative to XML that’s gaining traction in the dynamic scripting community.

XML Message (see earlier in this chapter) has several advantages over JSON Message:

  • XML is vastly more familiar to the IT community than JSON.

  • XML is more self-documenting. The header identifies which XML format is being used, and there’s often a schema or DTD that defines the format precisely.

  • XML has much more support in terms of libraries and tool support. JSON libraries tend to be simply about conversion, which its advocates would probably argue is all that’s required. XML, on the other hand, has support in terms of DTD and Schema validators, XPath tools to interrogate the data, XSLT processors to perform translations, and so on. Furthermore, many IDEs, editors, and debugging environments make XML easy to work with.

  • For any given task, developers usually have the luxury of choosing between several competing implementations.

Related Patterns

Ajax Stub

Being a portable object format, JSON is a useful way to facilitate calls from browser to server using an Ajax Stub (see earlier in this chapter) framework.

On-Demand JavaScript

Since a JSON Message is an ordinary JavaScript expression, it can be pulled in using On-Demand JavaScript. Data from external domains can be accessed this way, as explained in On-Demand JavaScript (Chapter 6).



[*] The WebDav protocol does just that. It adds several methods to HTTP, to support locking, property inspection, and moving resources around. These make REST easier to implement, but unfortunately, most Internet entities won’t understand them, so it defeats one of the main purposes of REST on the open Internet.

Get Ajax Design Patterns now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.