MSDN

Developer Network

RESTful Principles: Designing Great APIs

Representational State Transfer (REST) is an architectural style for designing networked applications. It relies on a stateless, client-server, cacheable communications protocol—most commonly the Hypertext Transfer Protocol (HTTP)—and is a dominant approach to building web services.

Adhering to RESTful principles leads to APIs that are scalable, maintainable, and easy to integrate with. This document outlines the core principles and how to apply them effectively.

Key REST Constraints

REST is defined by a set of architectural constraints. When an architecture adheres to these constraints, it is described as RESTful.

  1. Client-Server Architecture:

    There must be a clear separation between the client (user interface) and the server (data storage and logic). This separation allows for independent development and evolution of both the client and server.

  2. Statelessness:

    Each request from the client to the server must contain all the information necessary to understand and fulfill the request. The server should not store any client context between requests. This improves visibility, scalability, and reliability.

    Example: If a client needs to perform a sequence of operations, it must send all required state information with each request, or manage its own state and pass it back to the server as needed.
  3. Cacheability:

    Responses must implicitly or explicitly define themselves as cacheable or non-cacheable. This allows clients and intermediaries to reuse previously obtained responses, improving performance and scalability by reducing the need to repeatedly perform the same operation.

  4. Uniform Interface:

    This is the most fundamental constraint and is composed of four sub-constraints:

    • Identification of Resources: Resources (e.g., users, products, orders) are identified by URIs.
      /users/123
      /products/abc
    • Manipulation of Resources through Representations: Clients interact with resources via their representations (e.g., JSON, XML). When a client holds a representation of a resource, it has enough information to modify or delete the resource on the server, provided it has permission.
    • Self-descriptive Messages: Each message includes enough information to describe how to process the message. For example, HTTP headers indicate the media type of the representation.
    • Hypermedia as the Engine of Application State (HATEOAS): Clients should be able to discover available actions and navigate through the application state by following links provided in the server's responses. This makes the API discoverable and less brittle.
      {
        "orderId": "ORD789",
        "status": "processing",
        "links": [
          { "rel": "self", "href": "/orders/ORD789" },
          { "rel": "cancel", "href": "/orders/ORD789/cancel", "method": "POST" },
          { "rel": "update", "href": "/orders/ORD789", "method": "PUT" }
        ]
      }
  5. Layered System:

    A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way. Intermediary servers (like load balancers, proxies, and gateways) can be used to enhance scalability, security, and performance.

  6. Code on Demand (Optional):

    REST allows clients to download and execute code (e.g., JavaScript) from the server. This can reduce the need for pre-coding all functionality on the client, enabling more dynamic behavior.

Common RESTful Practices

Resource Naming

Use nouns for resource URIs, not verbs. URIs should represent resources, and HTTP methods (GET, POST, PUT, DELETE, etc.) should represent the actions performed on those resources.

Bad Practice Good Practice
/getAllUsers /users (with GET method)
/deleteOrder?id=123 /orders/123 (with DELETE method)
/updateProduct /products/abc (with PUT or PATCH method)

HTTP Methods (Verbs)

Leverage HTTP methods to indicate the intended operation on a resource:

Status Codes

Use standard HTTP status codes to communicate the outcome of a request:

Request and Response Payloads

Use standard formats like JSON for request and response bodies. Ensure consistency and provide clear schema definitions.

Error Handling

When an error occurs (4xx or 5xx status codes), provide a meaningful error response body, typically in JSON format, that includes an error code, a human-readable message, and potentially details for debugging.

{
  "error": {
    "code": "INVALID_INPUT",
    "message": "The provided email address is not valid.",
    "details": "Field 'email' failed validation."
  }
}

Benefits of RESTful APIs

By following these principles, you can design robust, efficient, and user-friendly APIs that power modern web applications and services.