Photo by Aleksandar Cvetanovic on Unsplash
Understanding RESTful APIs: The Basics, Guidelines, and Best Practices
When it comes to API architecture and design, REST comes first in our minds. But,
What is REST?
REST stands for Representational State Transfer. It is an architectural style that defines a set of constraints for designing networked applications. When we have a resource, such as a product like mango, it typically has some state or attributes associated with it. To represent this state, we store the properties of the mango in a database or other storage system. REST provides a standardized set of principles and constraints that enable us to transfer or share the state of the mango resource. These constraints are not strictly enforced but serve as recommendations for building scalable and interoperable web services.
In the image shown above, we initially represent the state of an actual product, and subsequently share it through an API, adhering to the REST constraints.
API stands for Application Programming Interface, which provides a standardized interface that allows interested parties to interact with or consume resources.
If we share the state of an entity using an API while adhering to the REST constraints, we can refer to this API as a RESTful API.
What are REST constraints?
REST (Representational State Transfer) defines a set of constraints that guide the design and implementation of web services. These constraints ensure scalability, simplicity, and uniformity in how resources are accessed and manipulated.
Here are the key REST constraints with examples:
Client-Server Separation:
The client and server are separate entities, each with distinct responsibilities. The client is responsible for the user interface and user experience, while the server manages resources and performs processing. For example, in a RESTful API:
The client sends a request to the server to retrieve product information.
The server processes the request, accesses the database, and sends the response containing the requested product data back to the client.
Stateless Communication:
The server does not store any client state between requests. Each request from the client must contain all the necessary information for the server to understand and process it. For example:
The client includes authentication credentials (e.g., tokens) with each request to the server.
The server validates the credentials and processes the request accordingly without relying on any previous client state.
Cacheability:
Responses from the server can be cached by the client or intermediaries (such as proxies) to improve performance and reduce network traffic. For example:
The server adds cache-control headers to the response, indicating whether the response can be cached and for how long.
The client or intermediary caches the response and reuses it for subsequent requests to the same resource, eliminating the need to fetch the data from the server again.
Uniform Interface:
RESTful APIs have a uniform and consistent interface that simplifies communication between clients and servers. This constraint includes:
Resource identification through URLs (e.g., /products/123).
Manipulation of resources through standard HTTP methods (GET, POST, PUT, DELETE).
Use of standard media types (such as JSON or XML) for representing and exchanging data.
Layered System:
A RESTful API can be composed of multiple layers, such as load balancers, caching servers, and gateways. Each layer contributes to the overall system architecture and can be modified independently without affecting other layers. For example:
A load balancer distributes incoming requests across multiple servers to handle high traffic efficiently.
A caching server sits between the client and the server, caching responses to reduce server load and improve response times.
The Uniform HTTP Interface in RESTful APIs
While REST does not explicitly mandate the use of HTTP as the underlying protocol, it is widely used in practice due to its uniform interface and widespread support. The reason HTTP is commonly used with REST is because it provides a standardized set of methods and status codes that align well with the principles of REST.
The uniform interface in the context of HTTP refers to the consistent way in which clients interact with resources through well-defined methods and receive standardized responses from servers. This interface includes the following elements:
HTTP Methods (Verbs): HTTP defines a set of methods that correspond to different actions on resources. The commonly used HTTP methods in RESTful APIs include:
GET: Retrieves the representation of a resource without modifying it.
POST: Submits data to the server to create a new resource.
PUT: Updates the representation of a resource with the provided data.
DELETE: Removes a resource identified by the URL.
Resource Identifiers (URLs): Resources are identified using URLs (Uniform Resource Locators). URLs provide a consistent way to uniquely address and access resources within a RESTful API.
Headers: HTTP headers provide additional information and instructions to the server and client. They can be used for various purposes, such as authentication, caching, content negotiation, and request/response metadata.
Status Codes: HTTP status codes indicate the outcome of a request. They provide information about the success or failure of the request and offer specific details on the status of the resource. Some commonly used status codes include 200 (OK), 201 (Created), 404 (Not Found), and 500 (Internal Server Error).
By leveraging this uniform HTTP interface, RESTful APIs achieve a consistent and standardized way of interacting with resources across different clients and servers. This uniformity simplifies the development and integration of web services and enables interoperability between various systems and technologies.
The Nature of REST Constraints as Guidelines and Essential Constraints to Follow
REST constraints provide flexible guidelines for designing web services, allowing for interpretation and adaptation based on specific needs. While they are not rigid rules, the uniform interface constraint is essential and should always be followed. This constraint ensures consistent and predictable communication between clients and servers, promoting intuitive and reusable APIs that work well across platforms. While it is important to strive for adherence to all REST constraints, the level of implementation may vary based on individual requirements, making them guidelines rather than strict rules. Nonetheless, they promote best practices and interoperability in RESTful API design.
HTTP in REST: Route Design, Verbs, and Status Codes
Heading: HTTP in REST: Route Design, Verbs, and Status Codes
In REST, HTTP plays a crucial role as the underlying protocol for communication between clients and servers. It provides a standardized and uniform interface for designing RESTful APIs, encompassing route design, HTTP verbs, and status codes.
Route Design: HTTP route design involves defining the structure of resource URLs in a RESTful API. The routes should follow a hierarchical and logical pattern that represents the resources and their relationships. For example, /products could be the base route for accessing product-related resources, and appending a specific product ID like /products/123 would retrieve or modify a specific product.
HTTP Verbs: HTTP verbs, also known as HTTP methods, determine the action to be performed on a resource. RESTful APIs utilize the following commonly used HTTP verbs:
GET: Retrieves the representation of a resource. It is used for fetching data without modifying it.
POST: Submits data to the server to create a new resource.
PUT: Updates the representation of a resource with the provided data. It can either create a new resource or completely replace an existing one.
PATCH: Modifies a partial representation of a resource. It is typically used for making incremental changes.
DELETE: Removes a resource identified by the URL.
By mapping these verbs to specific routes, clients can perform the desired actions on resources within the API.
Status Codes: HTTP status codes indicate the outcome of a request and provide information about the status of a resource. RESTful APIs utilize status codes to communicate the success or failure of a request accurately. Some commonly used HTTP status codes in REST include:
200 OK: The request was successful, and the server returns the requested resource.
201 Created: A new resource was successfully created.
400 Bad Request: The server could not understand the request due to invalid syntax or parameters.
404 Not Found: The requested resource does not exist on the server.
500 Internal Server Error: An unexpected error occurred on the server.
These status codes, along with appropriate response payloads, help clients understand the outcome of their requests and handle errors gracefully.
Let's explain and complete the examples for each HTTP verb in a consistent manner:
To create one or multiple mangoes:
Example:
POST /mangoes
Description: Create one or multiple mango resources.
Request body: The data representing the mango(s) to be created.
To update a mango:
Example:
PUT /mangoes/:mangoId
Description: Update a specific mango resource identified by
:mangoId
.Request body: The updated data for the mango.
To get a mango:
Example:
GET /mangoes/:mangoId
Description: Retrieve a specific mango resource identified by
:mangoId
.
To get multiple mangoes:
Example:
GET /mangoes
Description: Retrieve a list of all mango resources.
To update a certain part of a mango (partial update):
Example:
PATCH /mangoes/:mangoId
Description: Update a specific part of the mango resource identified by
:mangoId
.Request body: The specific fields and their updated values for the mango.
To delete a mango:
Example:
DELETE /mangoes/:mangoId
Description: Delete a specific mango resource identified by
:mangoId
.
Additionally, considering the relationship between mangoes and a mango farm:
To get mangoes belonging to a specific mango farm:
Example:
GET /mango-farms/:mangoFarmId/mangoes
Description: Retrieve all mango resources that belong to the mango farm identified by
:mangoFarmId
.
To create a mango belonging to a specific mango farm:
Example:
POST /mango-farms/:mangoFarmId/mangoes
Description: Create a new mango resource that belongs to the mango farm identified by
:mangoFarmId
.Request body: The data representing the new mango to be created.
These examples demonstrate consistent and common usage patterns of HTTP verbs in RESTful APIs. The routes follow the RESTful convention of using plural resource names and include the necessary parameters to identify and operate on specific resources.