AjaxPatterns
This is the original book draft version for the RPC Service Ajax pattern, offered for historical purposes and as an anti-spam measure.
You're probably better off visiting the Live Wiki Version for RPC Service instead, where you can make changes and see what others have written.

RPC Service

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

Developer Story

Dave's finished coding the back-end 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 "Forces" for “RESTful Service”.

Solution

Expose web services as Remote Procedural Calls (RPCs). Like REST, RPC is a broad term. And 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 characterised 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 back-end is developed, and a remoting framework acts as a bridge between client and server, allowing the client to directly invoke back-end 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 back-end 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 returned with the response. There are many frameworks available to automatically expose back-end 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 back-end operations as HTTP-based, services which 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 SOAP 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” frameworks such as 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 Call”s directly or even with an XMLHttpRequest wrapper. It instead calls a generic remoting function, capable of invoking operations on the back-end. See the Refactoring Illustration of “Ajax Stub” 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 be. “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 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 calls 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
18:30:00 , false , undefined , undefined)

Kiko invoke 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 wanted 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 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, 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 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=getCategories.

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=getCart. 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” 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” automates the production of RPC Services.

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” or a “XML Message”.

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.

Live Wiki Version for RPC Service