lördag 25 januari 2025

What is a REST API?

People mistakenly believe they are designing REST API:s but actually they design RPC API:s. 
The misconception has its root in the lack of theoretical knowledge about REST API and the RESTFul Principles. 
I don’t trust people that have a very rigid view about how a REST API should be implemented, claiming that their way to design is best practices on the Internet. 
The truth is that the majority of developers don’t know the basic principles of REST API. Majority of Microservices out there are RPC API:s not REST API:s. And that was a frustration Roy Fielding (the father of REST) already expressed in 2008.
 
There are few similarities:
  • Both use HTTP
  • Client-Server Model
 
There are crucial distinctions:

  • Resource-Oriented vs. Action-Oriented:
    • REST: Focuses on manipulating resources (e.g., "users", "products") through HTTP verbs (GET, POST, PUT, PATCH, DELETE) and respecting the semantics of the verbs and the characteristics, like the idempotency of some verbs.
    • RPC: Primarily focuses on executing remote procedures or functions (e.g., "getUserById", "createProduct").
  • Data Format:
    • REST: Often leverages standardized data formats like JSON or XML.
    • RPC: Can use various data formats, including custom ones.
  • Semantics of the URL:
    • REST: URLs typically represent resources (e.g., /users/123, /products).
    • RPC: URLs might reflect function names (e.g., /getUser, /createProduct).
  •  Flexibility:
    • REST: Generally more flexible and easier to evolve due to its focus on resources and standard HTTP verbs.
    • RPC: Can be more tightly coupled to specific implementations.
While both can use HTTP and operate within a client-server model, REST emphasizes a resource-oriented approach with standardized HTTP verbs, while RPC focuses on remote procedure calls, often with less emphasis on resource representation and the creation of semantic correctness.
Roy Fielding, the creator of REST, expressed significant frustration with how the term "REST API" is commonly misused. Here's a breakdown of his key concerns:
 
Misinterpretation of Core Principles:

  • Focus on HTTP: Many developers perceive REST solely as using HTTP, overlooking its architectural constraints and guiding principles. Fielding emphasizes that REST is not just about using HTTP verbs (GET, POST, PUT, PATCH, DELETE) but about adhering to a specific architectural style, understanding and implementing the semantics of the verbs within constraints like statelessness, cacheability, and uniform interface. Despite some API:s have idempotency as a requirement, they don’t use verbs that warrant idempotency and respect the semantics of the endpoints.
  • Ignoring HATEOAS: A core principle of REST is "Hypermedia as the Engine of Application State" (HATEOAS). This means that the API should provide links within its responses, allowing clients to discover and navigate resources dynamically. Many so-called "REST APIs" lack this crucial aspect, relying on pre-defined client-side logic.
  • Oversimplification and Misuse: "REST" as a Buzzword: The term "REST API" has become a buzzword, often used indiscriminately for any HTTP-based API, regardless of its actual adherence to REST principles. This dilutes the meaning and makes it difficult to distinguish truly RESTful APIs from others.
  • Focus on CRUD Operations: Many APIs labeled as "RESTful" primarily focus on CRUD operations (Create, Read, Update, Delete) on resources, neglecting the broader architectural considerations of REST. REST API don’t need to be CRUD API:s, an API can be Decision Making API or other implementation style dictated by the requirements, the important thing is the broader architectural considerations and semantics.

Impact on API Design and Evolution:

  • Limited Flexibility: Misinterpreting REST can lead to API designs that are less flexible and more tightly coupled to specific client implementations.
  • Hindered Innovation: By not adhering to true REST principles, developers miss out on the potential benefits of a more flexible and evolvable architecture.
Fielding laments that the term "REST API" has been widely misused and misunderstood, leading to suboptimal API designs and hindering the realization of the full potential of RESTful architectures. He emphasizes that true REST is more than just using HTTP; it's about adhering to a specific set of architectural constraints that promote flexibility, scalability, and evolvability.

Many developers misuse HTTP verbs, leading to inconsistent and unpredictable APIs. 

  • Common Misuses:
    •  Overusing POST: Many developers use POST for updates (instead of PUT or PATCH), even when the operation is idempotent. This violates the intended semantics of POST, which is typically for creating new resources, if the idempotency requirement is not included on creation.
    • For Idempotent Operations: Using POST for operations that should be idempotent (like updating a specific resource) can lead to unexpected side effects if the request is repeated.
    • Ignoring PUT vs. PATCH: Using POST for Partial Updates: Many use POST for partial updates (updating only specific fields of a resource), while PATCH is the correct verb for this purpose.
  • Misinterpreting Idempotency:
    • Confusing with Safety: Some developers mistakenly believe that all idempotent operations are safe (have no side effects). While all safe methods are idempotent, the reverse is not true. PUT and DELETE are idempotent but not safe.
    •  Consequences: Inconsistent APIs: Misusing verbs makes APIs harder to understand and use, leading to confusion and errors.
    • Unexpected Behavior: Incorrect verb usage can result in unexpected side effects, such as unintended data modifications or multiple creations of the same resource.
    • Limited Caching: Improper use of verbs can hinder caching mechanisms, as caches may not be able to effectively store and reuse responses.
    • Reduced Interoperability: APIs that don't adhere to HTTP verb semantics are less interoperable with other systems and tools that rely on these standards.
Best Practices? 
  • Use Verbs Correctly:
    • GET: Retrieve a resource.
    • POST: Create a new resource. (If and only if idempotency is not required)
    • PUT: Replace an entire resource. (also for creation if idempotency is required)
    • PATCH: Update specific parts of a resource.
    • DELETE: Remove a resource.
  • Understand Idempotency: Be aware of which verbs are idempotent and design your API accordingly,
  • Follow HTTP Standards: Adhere to the HTTP specification and best practices for verb usage.
By adhering to these principles, developers can create more robust, predictable, and maintainable API:s that are easier to use and integrate with other systems.
While POST is generally used for creating resources, there are situations where you need idempotency in a creation scenario. Here's how you can achieve that with PUT:

Idempotency

  • Concept: Introduce a unique identifier (like a UUID) within the request body if you rely on calling clients or implement a server-side identification for requests.
  • Implementation: 
    •  The server checks for this identifier.
    • If the identifier is encountered for the first time, the resource is created, and the identifier is associated with it.
    • If the identifier is already present, returns the existing resource (if the creation was successful in the past).
While POST is not inherently idempotent therefore have to be used ONLY when idempotency is not required, you have to use PUT when idempotency is required. PUT is idempotent according to HTTP Specification and it helps you to design a semantically right and more RESTFul API.
At the end Richmond Maturity Model explain very well what we are talking about: