0% found this document useful (0 votes)
68 views5 pages

Apigee Web Api Design The Missing Link Ebook 1 4

The document discusses improving web APIs by including links in resource representations. It describes how including links avoids the need to look up URI templates and makes relationships between resources more clear. URI templates still serve a purpose for querying when links are not available. The analogy of links and templates to web navigation is also discussed.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views5 pages

Apigee Web Api Design The Missing Link Ebook 1 4

The document discusses improving web APIs by including links in resource representations. It describes how including links avoids the need to look up URI templates and makes relationships between resources more clear. URI templates still serve a purpose for querying when links are not available. The analogy of links and templates to web navigation is also discussed.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

The ownerID field expresses the relationship. A better way to express relationships is to use links.

If your
web APIs do not include links today, a first step is simply to add some links without making other changes,
like this:

{“id”: “12345678”,

“kind”: “Dog”

“name”: “Lassie”,

“furColor”: “brown”,

“ownerID”: “98765432”,

ownerLink”: “https://dogtracker.com/persons/98765432”

If the representation of the owner previously looked like this

{“id”:”98765432”,

“kind”: “Person”

“name”: “Joe Carraclough”,

“hairColor”: “brown”

you can improve it by making it look like this:

{“id”:”98765432”,

“kind”: “Person”

“name”: “Joe Carraclough”,

“hairColor”: “brown”,

“dogsLink”: “https://dogtracker.com/persons/98765432/dogs”

16
Why is this better?
In the original example, if you had the representation of Lassie, and you wanted to get the representation
of Lassie’s owner, Joe, you would have to look in the documentation of the API to find a suitable URI
template you could use to construct a URL to locate Joe. In the representation of Lassie, you have an
ownerID, and you’re looking for a URL template that takes an ownerID as a variable and produces
a URL that locates an owner. This approach has several drawbacks. One is that it requires you to go
hunting in the documentation rather than just looking at the data. Another is that there isn’t really a
good documentation convention for describing which property values found in representations can
be plugged into which templates, so some amount of guesswork is usually necessary, even given the
right documentation. In this example, you would have to know that owners are people, and look for
templates that take the ID of a person as a variable. A third drawback is that you have to write code
that will combine the ownerID property value with the template and produce a URL. The URI template
specification calls such code a template processor. For simple templates, this code is fairly trivial, but it
still has to be written and debugged.

By contrast, in our modified design, there is less to learn, and using the API is easier. Joe’s URL is right
there in the data for you to see, so you don’t have to go digging through the documentation for anything.
Your client code is also easier to write—simply pick up the value of ownerLink and use it in an HTTP
request. You don’t have to write code to construct a URL from a template and a variable value, and
you can even write and use general-purpose code that follows these links without having any built-in
knowledge of the API. Adding dogsLink to the owner resource provides even more value. Without
dogsLink, it is not obvious from the data that it is even possible to navigate from an owner to their dogs.
An increasing number of APIs from major companies on the web are including links in their data. We’ll
share some examples from Google and GitHub in the Who uses links? section.

Are URI templates still needed when you have links?


Yes, they are still important. Links express where you can go from where you are. They are the signposts for
the paved paths to traverse the system. URI templates are like shortcuts, a way to cut across the lawn
when you have a very specific destination in mind. In an API that has links, it often happens that there is a
handy link in a resource whose representation you already have that takes you where you want to go. It
also happens that there is not a link, or that the path to get there by following links is excessively long. In
that case, you need another way to locate the resource you need to get to. The URI templates provide a
way to do this.

17
URI templates are most useful if they accept variables whose values are easy for humans to read and
remember. For example, the URL template

https://dogtracker.com/persons/{personID}

has some utility, but remembering the personID can be almost as hard as remembering the whole URL if
personID is some obscure and lengthy identifier. By contrast, the following template

https://dogtracker.com/persons/{personName}

is more useful because names are very fundamental to the way in which humans deal with the world.

This is the same reason that domain names exist to map names to IP addresses. On the web, when you
follow a link to the server that runs the Google Cloud blog, for example, you don’t care whether the link
contains a domain name or an IP address—you just use it. Having the domain name blog.apgiee.com does
improve the experience if you are typing the URL6.

An analogy with the World Wide Web


The HTML web is a network of documents connected by HTML links. A fundamental way of navigating
the web is to follow links to hop from one resource to another. You can also type in a URL directly, or
access it from a bookmark, but there is a limit to the number of URLs you can know or bookmark. At the
beginning of the web, following links or typing in URLs were the only navigation methods that existed.
Some companies (Yahoo! being the most famous) extended the link traversal mechanism to address the
problem of discovery of resources. The idea was that https://yahoo.com would be the single root of the
web, and from there you could navigate through the links in Yahoo categories to get to anywhere you
needed to go. Other companies (Google being the most famous) let you perform a search of web pages
using information you know is on those pages (keywords or strings that appeared in the text of the page).
Having discovered those pages, you can click on the links they contain to get to new pages until you run
out of useful links to click and have to go back to Google to do another search. We now all take it for
granted that the way you work with the web is through a combination of search plus link traversal.

6
Of course, domain names are also important for separating the logical web from the physical infrastructure, even for links.

18
One way to think about the URI templates of a typical web API is that they are analogous to Google
searches. They allow you to locate resources whose URL you don’t know using bits of information from
those resources that you do know. Most people know how to perform a Google search through a web
browser using URLs like this one:

https://www.google.com/search?q=web+api+design

When web API designers define URL templates that look like this

https://dogtracker.com/persons/{personId}/dogs

they are in fact specifying a specialized query language for their application. The same query could be
expressed as:

https://dogtracker.com/search?type=Dog&ownerId={personId}

Unlike Google, which provides a universal search language across all websites, URI templates define a
query language that is specific to a particular set of resources—your API. Designing a query language
specific to your API can be helpful since you can use knowledge of your data and use cases to define a
more usable and understandable query capability for your resources and to limit the cost of implementing
it. The downside is that the query language for each API has to be learned individually. If there were a
universal language for query that was supported by all APIs, the productivity of all API client application
developers would be improved. We will look at how to make query URLs regular and predictable in the
section entitled Designing query URLs.

Many people have been happy with the success of URI templates for locating resources via queries and
have ignored the value of the other mechanism—links. On the other extreme, some link advocates have
insisted on a single root model without the use of query/search. These two techniques are valuable
complements to each other for web APIs just as they are for the HTML web.

19
Including links, step 2
If all you do is add URL-valued properties like those shown above, you will already have made a significant
improvement to your API. You could make the URL-valued properties read-only, and continue to do
updates the way you do today. For example, if you want to change Lassie’s owner to the Duke of Rudling,
you would modify Lassie using a PUT or PATCH request to change the value of the ownerID to be the
Duke’s ID, and the ownerLink property would be recalculated by the server. If you are evolving an
existing API, this is a very practical step to take. However, if you are designing a new API, you may want to
go one step further with links.

To motivate the next step, consider the following example. Suppose dogs can be owned by either people
or institutions (e.g. companies, churches, governments, charities, and NGOs). Our dog tracker site is
motivated to allow this model so that they can track ownership of police dogs and other working dogs that
do not belong to individuals. Suppose also that the institutions are stored in a different table (or database)
from dogs, with their own set of IDs. At this point, it is no longer enough to have an ownerID property
with a simple value to reference the owner—you also need to specify what type of owner it is, so the
server knows what table (or database) to look in. Multiple solutions are possible: You could have ownerID
and ownerType properties, or you could have separate personOwnerID and institutionalOwnerID
properties only one of which may be set at a time. You could also invent a compound owner value that
encoded both the type and the ID. Each of these solutions may have its merits and demerits, but a very
elegant and flexible option is to use links to solve the problem. Imagine that we modify the example to
look like this:

{ “self”: “https://dogtracker.com/dogs/12345678”,

“id”: “12345678”,

“kind”: “Dog”

“name”: “Lassie”,

“furColor”: “brown”,

“owner”: “https://dogtracker.com/persons/98765432”

The explicit change is that ownerID property has been dropped, and there is a single owner field that is
URL-valued. An implicit change is that the URL-valued owner property is now read-write rather than just
read-only. You can now easily accommodate both human and institutional owners by simply setting the
property to be the URL of a person or the URL of an institution. Clients have to be aware that the owner
URL may point to different sorts of resources, and they will have to be prepared to react differently
according to the data returned when navigating this link. Note that this is exactly the behavior of a web
browser—the browser will follow a link in a web page and then act appropriately according to what it finds

20

You might also like