Resources are mentioned in the HTTP and URI RFCs and are concepts defined by the REST architectural style in the Uniform Interface
constraint. In this article, extracted from Master Ruby Web APIs, we are going to define what a resource is exactly.
You probably already have an idea of what a resource is. The term has been used widely, and most of the times pretty accurately, in different web technologies.
After being defined as a part of the REST style, it was pragmatically introduced as the target of URLs (Uniform Resource Locators - RFC 1738) before being extended to URIs (Uniform Resource Identifier RFC 3986) and IRI (Internationalized Resource Identifier - RFC 3987).
Before we continue on resources, let’s define what these acronyms mean exactly.
URI vs URL vs URN
It is important to understand the difference between URL, URI, IRI and URN because they represent different concepts. Tim Berners-Lee defined in RFC 3986 a “Uniform Resource Identifier (URI)” as “a compact sequence of characters that identifies an abstract or physical resource” and claimed that a “URI can be further classified as a locator, a name, or both.”
He also stated that the term “Uniform Resource Locator” (URL) refers to the subset of URIs that, in addition to identifying a resource, provide a means of locating the resource by describing its primary access mechanism (e.g., its network ‘location’).
Got it?
Let me simplify this for you. Let’s say you are a resource -
- URLs are locators (hence the name). A URL is your home address: 12 Whatever Street, 11002, Paris.
- URNs are names. For you, a URN is your name: John Smith.
- URIs can be a locator (URL), a name (URN), or both.
Basically, all URLs are URIs, but not all URIs are URLs.
The only thing that can qualify a URI as a URL is if the latter includes how to find the former. www.google.com/account
is not a URL, just a URI. However, http://www.google.com/account
is a URL (and still a URI) because it includes the protocol (http://
) that can be used to access the resource (www.google.com/account
).
URNs are much simpler - they are just names.
An ISBN (like 978-0553293357
) is a unique identifier for a book, which makes it a URI, and more specifically, a URN.
Finally, IRIs are an extension of URIs meant to include characters from the Universal Character Set (Japanese Kanji, for example). Indeed, URIs are limited to a subset of the ASCII character set.
HTTP and URIs
In the scope of HTTP, URIs are “simply formatted strings which identify - via name, location, or any other characteristic - a resource.”
A resource
is the thing
living on the other side of a URI and a URI only points to one resource. That sounds rather abstract, so let’s look at the following example.
http://example.com/users
This URL points to a resource named users
. Note that we can never retrieve this resource; instead, we can only get a representation of it as defined by the Uniform Interface
constraint. So we can say that a resource never changes, only its representations do.
So how do we name resources? After all, resources are just abstract concepts pointed at by URIs. In theory, it can be anything since naming doesn’t matter to the machine that will be the final client of your web API.
But we must also consider that we are building for human beings and we are still far away from removing developers from the equation. Since we are building web APIs for humans, who will use them to implement their client code, we should use concepts and semantics that they will understand. This follows the same principle used in naming resources for websites.
The following is based on the best practices to build an easy-to-use API, and not really on web standards.
If I want to represent the concept of a list of users, I would just use the pluralized word users
, which is just a noun. Making a request to this URL would return a representation listing a bunch of users. Anyone would be able to understand this, and seeing the representation will just confirm their idea about this resource.
With the URL below, we are getting a list of users.
http://example.com/users
Verbs VS Nouns?
But shouldn’t we call it http://example.com/get_users
, so people understand it more easily?
The answer is no, but the question itself is not stupid. We just don’t have to include this get
in the URL because HTTP has us covered already. Thanks to HTTP methods, we are able to extract as much as possible from the URI pointing to a resource. The best practice here is to use only nouns for resources, and not include meaningless verbs or words.
Some people prefer to use singular names for their resources, like user
. This choice is up to you, but I recommend simply using the plural version. Whatever you decide, stick to it. Don’t use /users
and /user/:id
in the same API - it’s just confusing for developers. Don’t forget that your goal is to build something easy-to-use for them, not you. Think about them before thinking about what you prefer.
Going further
As said at the beginning of this article, you’ve just read an extract from Master Ruby Web APIs. If you’d like to learn more about HTTP and how to build web APIs with Ruby, feel free to check it out. While the book is targeted at web APIs, you will still learn a ton of ways to improve regular web applications.