When working with APIs you may come across the term REST or RESTful. REST stands for Representational State Transfer. In essence, REST is a set of recommendations that an API can adhere to. This makes designing the API easier and using the API more predictable.
But how did we get to this point? Before REST, the main approach to designing web APIs was to use the Simple Object Access Protocol (SOAP). Where REST is an architecture style, SOAP is an officially standardized protocol maintained by the World Wide Web Consortium (W3C). Part of SOAP's allure early on, as well as it's eventual fall from popularity, was the strict and verbose nature of the standard. SOAP is tied to XML, includes security and authorization features, and works over a variety of protocols like HTTP and STMP. While most of these can be benefits to some organizations, the complexity that comes with the standard makes implementation more difficult.
REST was created to combat many of the problems of SOAP. Originally defined by Roy Fielding in 2000, REST has become one of the most popular ways to develop web services today. Where SOAP is a strict standard, Fielding's REST is an architecture style made up of six guiding constraints. It's also not tied to XML, even though many early REST APIs used it. Most current implementations use JSON instead.
The six guiding constraints of REST
REST's approach to guidelines allows APIs to be more modular and layered. As Fielding puts it:
REST is optimized for the common case so that the constraints it applies to the Web architecture will also be optimized for the common case.
Developers can add the functionality they need, while still providing some uniformity. The constraints, in no particular order, are as follows:
- Client-server: The client and server act independently. There is a clear separation of concerns, and requests and responses are exchanged to communicate.
- Stateless: Each request is self-contained in that it includes any information needed for the server to understand the request. The client can hold session state, but the server doesn't store any context.
- Cache: Designed to encourage caching, REST expects responses to be labeled as cacheable or non-cacheable. This allows clients to reuse responses for future requests if needed.
- Uniform Interface: The core distinguishing feature of REST is its interface. Regardless of where a resource (data) comes from, it is accessible via a predictable and consistent interface.
- Layered System: Where SOAP was very much "all-in", REST allows for a more modular, layered approach to building an API. For example, the API entry points can be decoupled from the auth server and the data sources as needed.
- Code on Demand (optional): The only optional constraint is one rarely seen in web APIs. Code on Demand allows the API to send executable code as the response. While this may sound appealing in certain circumstances, it is impractical when considering the variety of languages that the API consumer may use. In modern application's this also opens the door for additional client-side security concerns.
While these are guiding principles and constraints, they are not a set standard. This allows for some interpretation, however, the community does offer solutions like OpenAPI to try and solve some of the variability that may arise. It also allows more choice for features like authentication.
How it all works
With some foundational knowledge out of the way, let's look at how clients and servers use REST to interact. A REST API exposes endpoints. These are unique endpoints that build upon a core, base path. For example:
A base path may look like:
Endpoints may then look like:
/users /user /organizations/:id/teams /profile
Endpoints can be defined with fixed values, like
/users above, or through more dynamic paths like
:id is replaced with a specific user ID. Additionally, endpoints can accept query strings made up of properties and values that act as instructions for the endpoint. For example:
/users?limit=10&order=ascending may request a list of 10 users in ascending order. Combined, a full resource path ends up looking something like:
https://api.example.com/users?limit=10&order=ascending ^^Base Path ^^ Endpoint ^^Query String
These endpoints are then combined with a set of HTTP request methods to define the action they can take. These line up with the Create, Read, Update, and Delete verbs of "CRUD" applications. The core HTTP methods that endpoints focus on are:
- GET: Retrieve/Read data.
- POST: Create new data.
- PUT/PATCH: Update data.
- DELETE: Delete existing data.
GET and DELETE can interact with the endpoint itself, but POST and PUT/PATCH are capable of sending data in the body of the request. This is often as stringified JSON or Form data. All requests can, and often, contain a set of headers such as
Content-Type, and more that act to describe the request.
Once the client sends the request to the server, through the endpoint, the API server processes the request, performs the required action, and sends a response back. This response is normally in the form of an HTTP status code and a JSON object.
Beyond standard REST
As Fielding puts it in his original thesis:
REST is not intended to capture all possible uses of the Web protocol standards.
RESTful web services are dominant, but certain use cases have led to APIs that require more than REST can offer. Streaming, real-time communication, and data-heavy applications have pushed for different types of APIs.
One of the largest in this space is Facebook's GraphQL. Designed as a unified query language for APIs, GraphQL aims to give API consumers only the data they need, rather than large payloads that may contain excess content.
So is REST going away? Not any time soon. Even with the emergence of new approaches and standards, most of your integrations will still be RESTful. REST is still a safe option if you are building a new API today, but it may be worth considering alternatives like GraphQL, Falcor, or gRPC.