Master

Building a REST API

An API is the interface your frontend and mobile apps use to talk to your data. Learn to design clean REST endpoints, version them, and return consistent JSON the way a real product API does.

What you will see

Building a REST API GET /api/v1/posts: list posts (v1) GET /api/v2/posts: list posts (v2) Old clients keep running on v1: True

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Version your API path

1

Serve old and new API versions side by side.

print() print("Building a REST API") print("GET /api/v1/posts: list posts (v1)") print("GET /api/v2/posts: list posts (v2)") print("Old clients keep running on v1: True")

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Building a REST API GET /api/v1/posts: list posts (v1) GET /api/v2/posts: list posts (v2) Old clients keep running on v1: True
Ship incompatible changes as a new version so old clients keep working.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

A client sends an HTTP verb and path, the router matches the resource action, the handler queries the database, and a consistent JSON envelope is returned.
1 Client sends GET /api/v1/posts
↓
2 Router matches the listPosts handler
↓
3 Handler queries the posts table
↓
4 Rows are wrapped in the JSON envelope
↓
5 The response is sent as application/json
↓
6 The client parses the data
Why this works
Versioning from day one

Your API will change. Clients will break. The fix is to put a version in the path:

GET /api/v1/posts
GET /api/v2/posts

When you make an incompatible change, ship it as /api/v2/ and let old clients keep running on /api/v1/. This is how services like Stripe and GitHub evolve their APIs over years without breaking existing customers.

Examples

Resource-based routes

REST organises routes around **resources*: like users, posts, or orders. The same resource gets all four CRUD verbs:

router.get('/api/posts', listPosts);       // read all
router.get('/api/posts/:id', getPost);     // read one
router.post('/api/posts', createPost);     // create
router.put('/api/posts/:id', updatePost);  // update
router.delete('/api/posts/:id', deletePost); // delete

Notice there is no word like "delete" or "create" in the URL. The HTTP verb carries the meaning. This uniform style is what makes a large API predictable and easy to use.

Consistent JSON responses

Good APIs always respond the same way, so clients can depend on the shape.

function ok(res, data) {
  res.json({ success: true, data });
}

function fail(res, status, message) {
  res.status(status).json({ success: false, message });
}

Now every request gets { success, data } or { success, message }. A client can build its logic once around that shape. Consistency is what separates a prototype from a product API.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Error handling and validation
Previous Lesson
Error handling and validation
Next Lesson
Automated testing
Automated testing →