RESTful Web Services

Representational State Transfer architecture and API design principles.

Introduction: Beyond Websites to Web Services

In the early days, the web was primarily a collection of hyperlinked documents designed for human consumption. A browser (client) would request a webpage from a server, and the server would respond with a complete HTML document, styled with CSS and enhanced with JavaScript, all intended to be rendered on a screen for a person to read. While this model powers the visual web we browse every day, another, equally important web exists in the background: a web for applications.

Modern applications are rarely monolithic. Your mobile banking app, your smart home device, your social media feed. These applications constantly need to communicate with servers to fetch data, submit updates, and perform actions. They are not interested in receiving a fully formatted HTML page. Instead, they need a structured, predictable way to exchange raw data. This programmatic interaction between different software applications over a network is facilitated by an , or Application Programming Interface.

Over the years, many styles for building these web APIs have emerged, such as SOAP and RPC. However, one architectural style has become the de facto standard for building modern web services due to its simplicity, scalability, and alignment with the principles of the web itself: REST.

What is REST? An Architectural Style, Not a Protocol

It is crucial to understand that , which stands for Representational State Transfer, is not a protocol, a standard, or a specific technology. You cannot "install" REST. Instead, it is an architectural style, a set of guiding principles or constraints for designing networked applications. It was defined by Roy Fielding in his doctoral dissertation in 2000. Fielding was one of the principal authors of the HTTP specification, and the REST style essentially distills the architectural principles that made the World Wide Web so successful and scalable.

An API or web service that adheres to the constraints of REST is called a RESTful API. RESTful APIs use the existing features of the HTTP protocol to facilitate communication. Instead of inventing new mechanisms, REST leverages the power of URLs to identify resources and HTTP methods (GET, POST, PUT, DELETE) to define actions on those resources. This makes RESTful services intuitive and easy to use for anyone familiar with how the web works.

The Six Guiding Constraints of REST

For an API to be truly RESTful, it must follow six specific architectural constraints. These constraints work together to create a system that is simple, scalable, and reliable.

1. Client-Server Architecture
REST mandates a strict separation of concerns between the client and the server. The client is responsible for the user interface and user experience, while the server is responsible for data storage, business logic, and security. They are independent and can evolve separately. A server can be updated without impacting the client, and a new client application can be developed for a different platform (e.g., a new mobile app) as long as it speaks the same API language.
2. Stateless
This is perhaps the most fundamental constraint. In a RESTful architecture, all communication from the client to the server must contain all the information necessary for the server to understand and process the request. The server must not store any client context or session state between requests. Every request is treated as a new, independent transaction. If authentication is needed, the client must send its credentials with every single request. This statelessness greatly improves scalability, as any server can handle any client's request, simplifying server design and making it easy to add more servers to handle load.
3. Cacheable
Responses from a RESTful API must explicitly label themselves as cacheable or non-cacheable. When a response is marked as cacheable, the client is free to reuse that data for equivalent subsequent requests for a certain period. This improves performance and efficiency by reducing the number of requests that need to travel to the server. Caching is typically controlled via HTTP headers like Cache-Control.
4. Uniform Interface
To simplify and decouple the architecture, REST defines a uniform interface between clients and servers. This is the heart of the RESTful design and is itself composed of four sub-constraints:
  • Identification of Resources: Each individual resource must be uniquely identifiable through a stable identifier, which in web-based REST APIs is the URL. For example, /users/123 is the unique identifier for the user with ID 123.
  • Manipulation of Resources Through Representations: A client does not interact with the resource directly but with a representation of it. This representation is typically a data format like JSON or XML. When a client wants to update a user's data, it gets a representation of that user (e.g., a JSON object), modifies it, and sends the new representation back to the server.
  • Self-Descriptive Messages: Each message must contain enough information to describe how to process it. This is achieved through HTTP headers (e.g., Content-Type: application/json tells the receiver that the body is JSON) and the use of standard HTTP methods.
  • Hypermedia as the Engine of Application State (HATEOAS): This is the most mature and often least-implemented principle. It states that a client should be able to discover all available actions and resources through hyperlinks provided within the server's responses. The server's response for a user resource, for instance, might contain links to "edit-user" or "view-user-orders", guiding the client's next steps.
5. Layered System
A client should not be able to tell whether it is connected directly to the end server or to an intermediary along the way. A RESTful system can be composed of multiple layers of servers (e.g., security proxies, caching servers, load balancers). These layers can be added or removed as needed to improve performance, security, and scalability, without affecting the client, as long as they all adhere to the uniform interface.
6. Code on Demand (Optional)
This is the only optional constraint. It allows a server to temporarily extend or customize the functionality of a client by transferring executable code, such as JavaScript. The web browser is the most common example of this, where servers send JavaScript code that is then executed in the browser to create dynamic user experiences.

Designing a RESTful API: Resources and Actions

Designing a RESTful API involves thinking about your application in terms of resources and the standard operations that can be performed on them using HTTP methods. A resource is the key abstraction of information in REST. It can be a document, an image, a collection of other resources, or any other object.

Identifying Resources

The first step is to identify the "nouns" in your system. What are the key entities? For an e-commerce application, resources might include customers, products, orders, and items in a cart.

Each resource should have a unique, intuitive, and consistent URL. Best practices suggest:

  • Use nouns, not verbs, in URLs (e.g., /products, not /getProducts).
  • Use plural nouns for collections (e.g., /orders represents the list of all orders).
  • Use a unique ID to refer to a specific resource within a collection (e.g., /orders/123 refers to the specific order with ID 123).
  • Use nested paths for related resources (e.g., /orders/123/items represents the list of items in order 123).

Mapping Actions to HTTP Methods

Once you have defined your resource URLs, you use the standard HTTP methods to perform actions on them. This mapping is central to the REST philosophy. The most common operations are CRUD (Create, Read, Update, Delete).

OperationHTTP MethodExample URLDescription
Read (Collection)GET/productsRetrieve a list of all products.
Read (Specific Item)GET/products/456Retrieve the details of product 456.
CreatePOST/productsCreate a new product. The new product's data is sent in the request body.
Update (Full)PUT/products/456Replace the entire product 456 with the data sent in the request body.
Update (Partial)PATCH/products/456Apply a partial update to product 456 (e.g., change only the price).
DeleteDELETE/products/456Delete product 456.

Data Formats: The "Representations" in REST

REST is flexible regarding the format used for data representation, but the most widely used format by far is (JavaScript Object Notation). Its simple text-based structure of key-value pairs and arrays is easy for both humans and machines to understand.

A GET request to /products/456 might return the following JSON representation:

{
"id": 456,
"name": "Wireless Ergonomic Mouse",
"price": 49.99,
"in_stock": true,
"category": "Peripherals"
}

To update this product using PUT, a client would send a similar JSON object in the body of its request. The client and server use the Content-Type and Accept headers to negotiate and specify that they are communicating using the application/json media type. While JSON is dominant, RESTful APIs can also use other formats like XML, YAML, or even plain text.

    RESTful Web Services | Teleinf Edu