4

Roy Fielding writes

A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations.

How do you do this for system-to-system interfaces? Say the client wants to create an order in the server at http://my.server.org How is it supposed to learn that for creating an order it is supposed to use the url http://my.server.org/newOrder and not http://my.server.org/nO or anything else?

For a human interface (i.e. browser), I guess the server would provide some form of link (possibly in a form element) and the text around and in that link would tell a user which of the forms on that page is the correct one for creating an order (as supposed to creating a user or navigating to some search result)

What are the mechanics used for implementing this on the client side? And also: are they actually used or does the majority of people just hardwire the urls into the client?

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348

3 Answers3

6

How do you do this for system-to-system interfaces? Say the client wants to create an order in the server at http://my.server.org How is it supposed to learn that for creating an order it is supposed to use the url http://my.server.org/newOrder and not http://my.server.org/nO or anything else?

It doesn't learn. Machine clients, generally, can't "learn". Not yet at least, we're still pre-Skynet. You have to "teach" them.

But what the key is that you don't teach them URLs. You teach them relations.

Consider, in HTML...

<a rel="order" href="http://my.server.org/newOrder"/>

and

<a rel="order" href="http://my.server.org/nO"/>

You'll notice that the rel is the same, "order", but the URL is not.

In a "perfect" world, you system will have a single entry point, say, http://my.server.org/ and from there the client can find all of the rels that it needs to know about.

In practice, many systems have several "well known", and defined entry points from which the client can start, just as an expediency so the client does not alway have to start at the root of the system. These well known entry points have an implied commitment from the provider that these URLs won't be changing any time soon. That they're long lived, and the server will support them very well.

But once passed the entry point, any URL you find likely does not have such a promise behind it. The URL can be a one use only URL. It could be directed to different machines for, say, load balancing. Who knows. But as a consumer of the service, you really don't care what the URL is, you only care about the relation. The relation tells you the detail of the URL to use.

The documentation of your hypermedia API explains how to apply the uniform interface to each of the rels that your client will encounter. The client can't "intuit" that either, it has to be taught.

Basically, by teaching the client how to navigate the relations that it will or MAY find in the payloads it processes is how the client manipulates the hypermedia API. The payloads contain sign posts to show the way, but the server dictates where those sign posts go.

As for how often it is used, in the machine to machine world, likely not very much. Most systems aren't large enough where the URLs change enough to matter, and the clients are so few that changing the clients is not a significant burden. So most just hard code away.

But then, in the end, you just have bad clients. Nothing a REST system can do with a bad client. It can't tell them apart at runtime anyway.

Will Hartung
  • 115,893
  • 19
  • 128
  • 203
2

No matter how you publish an API (to be consumed by machines), it is possible to make breaking changes.

When wrapping your API behind a UI (such as HTML forms), you have the freedom to change the URI without breaking the user, but that is because the user is consuming an abstraction you provided. Change the URL schema without changing your form, and you'll still break the client.

A couple ways to avoid breaking machine clients (basically, supporting backward-compatibility):

  • Build in some sort of URL versioning
  • Do redirection from old URL schemas to your new schema
Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
1

We've quite sucessfully approached it the following way: expose a WADL file at the very root URL of the application describing the media types as well as where to find links in it and their semantics. I know this (WADL) is something seen critical by some in the REST community but I always felt intimidated by very URL focus of WADL only. Beyond all the religious debates we liked having a well defined way of documenting representations. There is a way to get around the URL focus of WADL and rather point out where links can be found in the representation and then rather document that. See that blog post (currently down because of maintenance so you might want to look at it in the Google cache) for details on the approach.

This results in only a single URL to be known by the client as he can find out about it accessing the WADL, and from then on just learn about the representation and where to find links, what HTTP method needs what parameters when being invoked and so on.

Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211
  • Nice to see someone using using WADL for dynamic runtime discovery of resources. Personally, I think in many cases a standard hypermedia enabled media-type is sufficient for discovery but WADL definitely seems like a valid option for this scenario. – Darrel Miller Jun 11 '11 at 15:57
  • Absolutely. The only detail is ensure there is some kind of contract and TTL given by the WADL so the client has some expectation as to how long the WADL document, and the links it provides, is valid for. I can't say whether it would make sense to use WADL at a fine grained level (different WADL for each resource and activity) vs a larger meta document describing a collection of services. – Will Hartung Jun 11 '11 at 21:58
  • It seems WADL was not really designed to point to links inside representations in the first place (hence the rather awkward usage of the parameter element). Might be worth a proposal to a next version of it. We usually had one WADL file per application as otherwise the overhead of repeatedly querying and interpreting WADL files would have been to high. Using WADL that way is a kind of neat answer to the question of the SOAP guys for a machine readable API documentation that you might even generate code from but still complies to the REST guidelines and even features HATEOAS. – Oliver Drotbohm Jun 13 '11 at 19:32