1
Understanding RESTful Core Concepts
The history of web services is a fascinating journey through the evolution of the way that systems are built, distributed, and scaled.
Initially, the monolithic approach, which involved developing everything within a single application and machine, was the standard architectural method for many years. However, the need to divide software into distinct components with separate responsibilities has transformed how we design and implement systems.
The need to integrate distributed systems composed of software running on separate machines has existed since the early days of computing, and its importance is increasing, as the way we develop software is moving from monoliths toward more distributed architectures.
The global spread of the Internet, especially the World Wide Web, brought about the standardization of communication protocols, such as Internet Protocol (IP), Transmission Control Protocol (TCP), and Hypertext Transfer Protocol (HTTP). The success of the World Wide Web and its support by different devices, operating systems, and applications brought the idea that the infrastructure of the web could be used for connecting applications in general. This is when the term web services was adopted for using web technologies to create APIs.
In this book, you will acquire the knowledge needed to be ready to develop and master the creation of RESTful web services, starting from the concepts to full implementation, following the best practices in the market.
This chapter will prepare you for the rest of your journey in this book, understanding what the Representational State Transfer (REST) architecture and RESTful API services are, how these terms differ from each other, principles, maturity levels, and guidelines, as well as the project you will be creating throughout this chapters to implement this knowledge.
The following topics will be covered in this chapter:
- Why REST?
- Principles of REST architecture
- Levels of a RESTful API
- Representing data with JavaScript Object Notation (JSON)
- The importance of guidelines for developing REST APIs
- Common REST API use cases
- Architecture impact on REST API design
- Alternatives to REST
Why REST?
To understand why REST is the dominating architectural style for most web services, we will need to understand what was available before the rise of REST and the challenges that made this change so important in the way that distributed services are built.
The pre-REST era
Before REST, the web services landscape was dominated by protocols such as Simple Object Access Protocol (SOAP) and Extensible Markup Language-Remote Procedure Call (XML-RPC). These were powerful but complex standards that allowed for detailed communication between clients and servers. However, they were often seen as cumbersome due to their verbose nature and the strict requirements they imposed on developers.
SOAP, for instance, required developers to write extensive XML documents with specific calls and responses. It was notorious for its complexity and difficulty in debugging. Similarly, XML-RPC, while simpler than SOAP, still involved significant overhead for simple requests and responses (e.g., verbose and complex XML formatting, serialization and deserialization, a text-based protocol, and parsing complexity). Both SOAP and XML-RPC only used the HTTP protocol as a transport and duplicated, in their own ways, several features that the protocol offered and that were also supported by the existing web infrastructure.
To overcome these challenges and improve the way the systems communicated with each other, REST was created and has been widely implemented since its inception.
Understanding REST
REST was introduced in 2000 by Dr. Roy Fielding in his doctoral dissertation titled Architectural Styles and the Design of Network-based Software Architectures.
This architectural style was proposed as a more efficient, flexible, and scalable alternative to the existing standards of the time, such as SOAP and XML-RPC.
Dr. Fielding's dissertation aimed to simplify the way web services were created and consumed, leveraging the existing capabilities of the HTTP protocol.
The key principles of REST - statelessness, cacheability, uniform interface, and a client-server architecture - were designed to make web services more intuitive and aligned with the design of the web itself.
We will be covering each one of these principles in detail in the Principles of REST architecture section.
When we implement the REST architecture into web services, applying all these key principles, then we can say that we have a RESTful API. Let us understand this difference better in the next session.
Unpacking RESTful
RESTful APIs represent an approach to designing web services that adhere to the principles of REST, so they are not the same.
While REST provides the theoretical framework for building scalable and interoperable systems, RESTful APIs put these principles into practice, enabling developers to create robust and flexible APIs that are easy to understand, maintain, and extend.
The introduction of RESTful APIs marked a significant shift in web services since developers quickly adopted REST due to its simplicity and the way it facilitated the development of scalable and performant web applications. RESTful APIs became the backbone of web communication, powering everything from social media platforms to e-commerce sites.
Now that we have a clear understanding of REST and RESTful, let's dive deep into the principles of REST architecture. This will give us a clearer understanding of its key principles and how to achieve them.
Principles of REST architecture
Up to this point, we have only mentioned the key principles of REST. Let us dive deeper to understand these principles in more detail.
Uniform interface
The uniform interface is the cornerstone of any REST design, promoting a standardized way of interacting with a given set of resources. This principle encompasses four key constraints:
- Identification of resources: Each resource, whether it is a document, image, or service, is identified using a unique uniform resource identifier (URI)
- Manipulation of resources via representations: When a client possesses a representation of a resource, along with any attached metadata, it can modify or delete the resource on the server if it has the necessary permissions
- Self-descriptive messages: Each message contains enough information to describe how to process it, which may include the representation format and the desired state transitions
- Hypermedia as the engine of application state (HATEOAS): Clients interact with a RESTful service entirely through hypermedia provided dynamically by application servers - a concept known as HATEOAS
Example: Imagine a library system where each book is a resource identified by an ISBN number (URI). When you want to borrow a book, you get a representation (a card with book details), which you use to check out the book. The library's checkout system tells you how to proceed (using self-descriptive messages), and the catalog guides you to related resources (HATEOAS), such as the author's other books.
Client-server separation
This principle enforces the separation of concerns by dividing the user interface concerns from the data storage concerns. This separation allows the client and server components to evolve independently, leading to a more flexible and scalable application architecture.
Figure 1.1 - Client-server diagram
Example: A user submits a form on a website with their data to finalize a checkout (client sending the request); this will be JSON using the POST
HTTP verb and will be received by the server. The server will receive the data, create this new resource with the customer data, store the customer data, place a new order, and return the appropriate response to the user.
Statelessness
In a RESTful service, each request from a client to a server must contain all the information the server needs to fulfill the request. The server does not store any session state about the client, which means that each request is independent and isolated.
Example: Each time you order a coffee at a café, you provide your full order details. The barista does not need to remember your previous orders; they just make the coffee based on the current order alone.
Cacheability
Responses must, implicitly or explicitly, define themselves as cacheable or not. This helps improve the network's efficiency by reducing client-server interactions for...