Beginner25 min read

RESTful API Design

Master REST architectural principles, resource naming conventions, HTTP method mapping, and best practices for designing clean, intuitive APIs.

What is REST?

REST stands for Representational State Transfer, an architectural style for designing networked applications. It was introduced by Roy Fielding in his 2000 doctoral dissertation and has become the dominant approach for building web APIs.

REST is not a protocol or a standard — it is a set of principles and constraints that, when followed, create APIs that are intuitive, scalable, and easy to use. A RESTful API treats everything as a resource (a user, a product, an order) and uses standard HTTP methods to interact with those resources.

The beauty of REST is its simplicity and uniformity. Once you understand the pattern, you can predict how an API works without reading documentation. If you know how to GET a user, you can probably guess how to DELETE a user. If you know how to list all products, you can probably guess how to create a new product.

REST is everywhere. The GitHub API, the Stripe API, the Twitter API, the Spotify API — nearly every major web service uses REST. Learning REST is learning the lingua franca of the modern web.

REST Core Principles

REST is built on six key constraints that define how a RESTful system should behave:

1. Client-Server Separation The client and server are independent. The client handles the user interface, the server handles data and logic. They communicate via HTTP. This separation allows them to evolve independently.

2. Statelessness Each request from client to server must contain all the information needed to understand and process it. The server does not store session state between requests. Authentication tokens, not server-side sessions. This makes APIs easier to scale horizontally.

3. Cacheability Responses must define whether they are cacheable or not. If a response is cacheable, the client can reuse it for equivalent requests later, reducing load and improving performance.

4. Uniform Interface Resources are identified by URLs (e.g., /users/123). Resources are manipulated using standard HTTP methods (GET, POST, PUT, DELETE). Responses are self-descriptive (include status codes, headers, content types). This uniform interface is what makes REST intuitive.

5. Layered System A client cannot tell whether it is connected directly to the end server or an intermediary (load balancer, cache, gateway). This allows for scalability and security through layers.

6. Code on Demand (Optional) Servers can extend client functionality by transferring executable code (like JavaScript). This constraint is optional and rarely used in modern REST APIs.

Resources: Nouns, Not Verbs

The most important rule in REST is that URLs should represent resources (nouns), not actions (verbs). Resources are things — users, products, orders, comments. Actions are what you do to those things — create, read, update, delete.

In REST, the HTTP method represents the action, and the URL represents the resource. This creates a clean, predictable pattern.

Bad (verbs in URLs):

html
POST /createUser
GET /getUser?id=123
POST /deleteUser
POST /updateUserEmail

Good (nouns in URLs, verbs in methods):

html
POST /users
GET /users/123
DELETE /users/123
PATCH /users/123/email

Notice how the good version uses plural nouns (/users, not /user) and lets the HTTP method describe the action. This is cleaner, more consistent, and easier to understand at a glance.

Resource naming conventions:

  • Use plural nouns for collections: /users, /products, /orders
  • Use specific IDs for individual resources: /users/123, /products/abc-xyz
  • Use nesting for relationships: /users/123/posts, /orders/456/items
  • Use query parameters for filtering and sorting: /users?role=admin&sort=created
  • Avoid deep nesting (max 2-3 levels): /users/123/posts/789/comments is getting too deep

HTTP Methods and CRUD Mapping

REST maps HTTP methods to CRUD (Create, Read, Update, Delete) operations. Each method has specific semantics and expected behavior:

GET — Retrieve a resource

  • Safe (no side effects), idempotent (multiple identical requests have the same effect)
  • GET /users → List all users
  • GET /users/123 → Get user with ID 123
  • GET /users/123/posts → Get posts for user 123

POST — Create a new resource

  • Not safe, not idempotent (each request creates a new resource)
  • POST /users with body { name: "Alice", email: "alice@example.com" } → Create new user
  • Response typically includes 201 Created status and Location header with URL of new resource

PUT — Replace an entire resource

  • Not safe, but idempotent (multiple identical requests have the same effect)
  • PUT /users/123 with body { name: "Alice Updated", email: "alice@new.com" } → Replace user 123
  • Requires sending the complete resource representation

PATCH — Partially update a resource

  • Not safe, generally idempotent
  • PATCH /users/123 with body { email: "alice@new.com" } → Update only email field
  • More efficient than PUT when changing a few fields

DELETE — Remove a resource

  • Not safe, but idempotent
  • DELETE /users/123 → Delete user 123
  • Typically returns 204 No Content or 200 OK with deletion confirmation

Idempotency matters for reliability. If a client sends the same GET or DELETE request twice due to a network error, the result is the same. But if it sends the same POST twice, it creates two resources — this is why POST is not idempotent.

Which URL structure follows REST best practices for getting all orders placed by user 123?

Advanced REST Concepts

Beyond the basics, REST includes some advanced concepts worth understanding:

HATEOAS (Hypermedia as the Engine of Application State) A truly RESTful API includes hyperlinks in responses that guide the client to related resources and available actions. This makes the API self-documenting and discoverable.

Example response:

json
{
  "id": 123,
  "name": "Alice",
  "_links": {
    "self": "/users/123",
    "posts": "/users/123/posts",
    "friends": "/users/123/friends"
  }
}

In practice, most APIs skip full HATEOAS because it adds complexity and clients often prefer simpler JSON. But the principle — that an API should guide clients through available actions — remains valuable.

Versioning APIs evolve. When you need to make breaking changes, version your API:

  • URL versioning: /v1/users, /v2/users
  • Header versioning: Accept: application/vnd.myapi.v2+json
  • Query parameter: /users?version=2

URL versioning is most common because it is explicit and easy to understand.

Content Negotiation Clients can request different formats using the Accept header:

  • Accept: application/json → Server returns JSON
  • Accept: application/xml → Server returns XML
  • Accept: text/csv → Server returns CSV

Most modern APIs just use JSON and ignore content negotiation, but it is part of the REST specification.

Ready to practice?

Create your free account to access the interactive code editor, run challenges, and track your progress.