I've been reading a lot about REST and how to do REST the "right way". Most resources use terms like RESTful web services or RESTful APIs, however none mention RESTful websites. I am confused by this given that I think of a website and an API as two different things. Yet, when, for example, designing a website using the Rails framework, you're constantly reminded about how RESTful everything is (or is supposed to be).
I get the fact that REST provides a lot of advantages (its architectural properties) for APIs (e.g. a JSON API), but I just don't see how a website benefits from being RESTful. As a simple example consider login functionality. In a REST fashion this can be modeled by making a Session model with logging in corresponding to creating a new sesssion, logging out destroying a session and so on. The URLs would look something like this:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/login(.:format) sessions#new
user_session POST /users/login(.:format) sessions#create
destroy_user_session DELETE /users/sign_out(.:format) sessions#destroy
However, these URLs are not very user friendly. From a users point of view it makes more sense to just have a /login path where the login form is displayed. It is also easier to remember. But if we make the URLs map like that they're not really (as) RESTful anymore; does /login identify a resource. If so which one?
Another example is the home page /home or just /. How does that fit into REST? On most websites the home page is a mashup of many different kinds of information and doesn't identify any single resource. For example it could be a page that lists the newest products in a catalog and the last date you logged in; two completely unrelated things. How is that RESTful?
I understand why having a RESTful API separate from a website makes sense, but my confusion lies with how REST applies to websites - if it even does.
Not all HTTP APIs are REST APIs. The API needs to meet the following architectural requirements to be considered a REST API: Client-server: REST applications have a server that manages application data and state. The server communicates with a client that handles the user interactions.
They help you out by providing developers with an API, or application programming interfaces. There are more than 16,000 APIs out there, and they can be helpful in gathering useful data from sites to use for your own applications. But not every site has them.
REST APIs support more features than HTTP APIs, while HTTP APIs are designed with minimal features so that they can be offered at a lower price. Choose REST APIs if you need features such as API keys, per-client throttling, request validation, AWS WAF integration, or private API endpoints.
REST APIs are obsolete. Fielding defined REST in his 2000 PhD dissertation “Architectural Styles and the Design of Network-based Software Architectures” at UC Irvine. Since then it has become the de facto for creating APIs.
The short answer is that no one talks about RESTful websites because websites are RESTful by default. You really have to try to make a non-RESTful website (though it has been done--see below).
The setup you're describing takes a lot of elements from REST, but it's not "REST" per se: it's a set of conventions designed for the convenience of server-side programmers. Most of today's web APIs only use a subset of the REST constraints, and it's a subset that doesn't include the main driving principle behind websites.
Let me back up a bit. Here's what websites and web APIs have in common: they both expose functionality through resources. Each resource is identified by a URL, and each responds to an appropriate subset of the standard HTTP methods. (This may seem obvious, but look at XML-RPC or SOAP, where there's only one URL for the whole system.) A resource might send documents to the client (in response to a GET request) and/or it might accept documents from the client (along with a POST or PUT request).
Now, the differences. Web APIs often map the four most common HTTP methods (POST, GET, PUT, DELETE) onto the four CRUD operations (Create, Read, Update, Delete). Web sites can't do this, because web sites run on HTML, and HTML forms only support two methods: GET and POST. And yet, a web site can easily describe all sorts of actions--"search", "next page", "purchase", "unfriend"--which are nontrivial to map onto CRUD.
That's because HTML supports links and forms. This is what's missing from the "Web API" branch of the family tree. Not the resources, but the machine-readable connections between resources. (To drop some REST jargon, this is "the hypermedia constraint" or "hypermedia as the engine of application state.")
"Web APIs" tend to ignore the hypermedia constraint because a) it's difficult to understand, and b) JSON doesn't support links or forms, so it's difficult to obey the hypermedia constraint even if you want to. (This is changing with the development of formats like JSON-LD, Hydra, and HAL.)
But the hypermedia constraint is literally what holds the Web together. Take away the links and the forms, and you'd be left with an unusable mess.
Python Challenge is a good example of a non-RESTful website. You get a starting URL and then you have to solve a little puzzle to figure out how to get to the next URL in the sequence. You still have resources, and each resource has a URL. But the connections between resources are obscured. This is fun as a game, but no one would run a serious website this way. Unfortunately, this is kind of where we are in terms of "Web APIs."
Further reading
As you can tell, this is a complex topic. At the risk of tooting my own horn, the "maturity model" I developed for a 2008 talk might help you understand the architectural difference between the World Wide Web (level 3) and most of today's APIs (level 2). I'd also recommend Steve Klabnik's Designing Hypermedia APIs, and my own RESTful Web APIs, which starts out by comparing a web API to a website that does exactly the same thing.
My earlier book, RESTful Web Services, also covers this topic, and it's free to read online. However, it's somewhat out of date (it was published in 2007), and in retrospect I don't think it pushes the hypermedia angle hard enough.
Miscellaneous
To briefly respond to a couple of minor points from your original question:
There is no technical difference between a web API and a website. A website is a web API that happens to serve HTML documents.
One URL is not more "RESTful" than another. This is solely a usability issue. On a technical level it doesn't matter at all what your URLs look like. /users/login.json
and /login
and /the-first-100-prime-numbers.gif
are all equally RESTful ways to refer to a login form.
The home page is a resource: it's a "home page" resource. Its job is to contain the most important bits of information, and to guide the client to other pages--either directly through links, or indirectly through a search form. A resource does not necessarily correspond to a row in a database or an object in an object model. A resource can be absolutely anything, even a real-world object or an abstract concept. The only restriction is that a resource must have a URL.
/login
is a URL, so yes, it identifies a resource. What kind of resource? If it's a typical scenario where sending "GET /login" gets you an HTML page with a login form, then it's a "login form" resource. If filling out the login form triggers a "POST /login" request, then it also acts a "login form processor" resource.
You might have better luck thinking of a resource in terms of the code that runs when a request for its URL comes in, rather than trying to map it to one particular "thing" in your dataset. That is, instead of trying to figure out what a resource is, think of it in terms of what it does.
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With