Skip to content
Muhammet Şafak
tr
Web Development 4 min read

Fundamentals of RESTful API Design

Practical rules for making an API predictable through the triangle of resources, HTTP methods, and status codes.


At some point I needed to add a mobile app or another client to my Laravel projects, so I naturally started writing APIs. My first APIs looked something like this: /user/fetch, /user/save, /order/list. They worked, but as the number of URLs grew it became increasingly hard to keep track of what each one actually did.

REST (Representational State Transfer) offers an established approach for avoiding that chaos. In this post I’ll cover the three fundamental building blocks of REST — resource, HTTP method, and status code. Understanding them is both sufficient and the easiest-to-overlook foundation for making an API predictable.

What is a Resource?

In REST, everything is a resource. A resource represents an entity in your application: a user, an order, a product, a comment, and so on. Resources are addressed via URLs.

Resource URLs are noun-based — they never contain verbs:

# Wrong
GET /fetch-users
POST /create-new-user

# Right
GET /users
POST /users

Using plural nouns is the common convention: /users, /orders, /products.

To access a specific instance of a resource, append its identifier to the URL:

GET /users/42        → user with ID 42
GET /orders/7        → order with ID 7

For related resources, use a nested structure:

GET /users/42/orders → orders belonging to user 42

HTTP Methods

While the URL identifies the resource, the HTTP method tells the server what to do with it. There are five primary methods:

MethodMeaningExample
GETRead the resourceGET /users/42
POSTCreate a new resourcePOST /users
PUTFully replace the resourcePUT /users/42
PATCHPartially update the resourcePATCH /users/42
DELETEDelete the resourceDELETE /users/42

Using these methods correctly makes an API predictable for anyone already familiar with REST. When you call GET /users/42 you know nothing on the server should change. When you call DELETE /users/42 it’s obvious what to expect.

In the old HTML-form world we only ever used GET and POST. In a REST API, leveraging all the available methods makes intent explicit.

Status Codes

An HTTP status code tells the client how the server responded to the request. The standard defines a few hundred codes, but in practice you only need to know a small subset.

Successful responses (2xx):

  • 200 OK — Request succeeded, data is returned
  • 201 Created — Resource was successfully created
  • 204 No Content — Successful, but there is nothing to return (typically after a DELETE)

Client errors (4xx):

  • 400 Bad Request — The submitted data is malformed or incomplete
  • 401 Unauthorized — Authentication is required
  • 403 Forbidden — Authenticated, but not authorized
  • 404 Not Found — The requested resource does not exist
  • 422 Unprocessable Entity — Data format is valid, but content failed validation

Server errors (5xx):

  • 500 Internal Server Error — An unexpected error occurred on the server side

Using these consistently matters. Returning 200 OK for every response and burying "error": true in the body technically works, but it goes against REST principles and makes life harder when you’re working with HTTP tooling (Postman, curl, browser extensions) because you have to parse the body to understand what actually happened.

A Real-World Example

A simple API design for an orders resource might look like this:

GET    /orders         → List all orders          → 200 OK
POST   /orders         → Create a new order       → 201 Created
GET    /orders/7       → Fetch order 7            → 200 OK
PUT    /orders/7       → Update the order         → 200 OK
DELETE /orders/7       → Delete the order         → 204 No Content

Five URLs and five methods cover all CRUD operations. Anyone familiar with this pattern can guess what the API is capable of without ever reading the code.

Why Does This Matter?

There is no requirement to follow REST conventions — PHP certainly won’t stop you. But for whoever is writing an API client (a mobile app, another service, a frontend), predictability is a huge quality-of-life improvement. Tools like Postman and Swagger also work significantly better with APIs that follow REST conventions.

Once I internalized all of this, I went back to my old /user/fetch-style URLs and fixed them one by one. It took a bit of time, but the confusion on the consumer side disappeared.

Tags: #API
Share:

Comments

Sign in with your GitHub account to join the discussion. Comments are stored in GitHub Discussions.

Related Posts

Search the site

Start typing to search posts, projects and pages.

Esc to close Powered by Pagefind