From Ajax Patterns
Tags: Delegate Facade Procedure Proxy Remote Remoting RPC SOAP WSDL
In A Blink
Diagram - E-Commerce Catalogue. methods: createProduct() deleteProduct() etc
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.
How do you expose services on the web?
- The browser-side of an Ajaxian application needs to call server-side services.
- There might be more than one browser-side application sharing the same server-side service.
- As well, it's often desirable for third-party applications to invoke the server-side service too.
- With numerous different applications - and a variety of developers - accessing the service, it ought to be easy to use.
- Taken as a whole, the server-based services in a single "application" form an Application Programming Interface ("API"). It's important that services work consistently within the API.
- The basic architecture of the web does not force any type of service architecture -a given service could be implemented in a wide variety of styles.
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. /match/createMatch?matchId=1995 or /match/updater?command=createMatch&matchId=1995.
- 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 more concrete forms of RPC:
- Procedure-style API: In the simplest case, it's just a matter of the API style: the server exposes verb-like URLs, and there's not necessarily any relationship between URLs and 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 more a whole slew of additional functionality, such as custom data types and asynchonous messaging. Unfortunately, the flexibility comes at a cost, and using SOAP can sometimes feel like driving in a nail with a two-ton truck. The protocol almost certainly automatic translation of SOAP calls to and from calls in the native languages being used. For instance, Enterprise Java Beans can be automatically be exposed as web services using fancy code generators or mediating proxies.
Where URLs for Restful Services are noun-based, those for RPC are verb-based. However, RPC can still benefit from certain RESTful principles:
- As with REST, read-only queries should be made as GET requests, meaning that you shouldn't pass a query in the body.
- State-affecting calls should be made using POST, with the command and arguments in the body. The command will already indicate the type of action that's occurring, so there's usually no need to use other HTTP methods such as PUT or DELETE.
- As with REST, 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.
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. One benefit would be caching, since GET responses can be cached, unlike POST responses. Also, POSTs could include all arguments inside the body, while still having a RPC-style URL like /?function=CreateAppt.
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:
You can also effect changes with the API. For example, you can tag an element by posting to a URL like this:
with a body like this:
Ajax Shop Demo
The Basic Ajax Shop Demo provides a web service to expose and manipulate store items and user shopping carts. In this demo, the cart and product services are refactored to 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 form:
services.phtml?command=queryType&someArg=someValue>, with the argument being optional. State-affecting commands instead require all arguments, including the command, to be posted to a simple URL:
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/run/shop/rpc/services.phtml?command=getCategories.
Reading an Individual Category
To drill down to an individual category, say "Movies", you GET http://ajaxify.com/run/shop/rpc/services.phtml?categoryName=Movies.
Reading Cart Contents
To read cart contents, you GET http://ajaxify.com/run/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.
RESTful Service is an alternative to RPC Service. The Solution of that pattern compares the two approaches. Note that a service with RPC-style URLs can still follow many tenets of REST, as discussed in the Solution above.
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 semantic nature.
Calling an RPC Service is like asking for something via your secretary.