Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

REST API design

After this lesson: I can design resource addresses and pick the right method for each job.

55 min lesson6 commandsPostgreSQL and PostgREST lab: a database and a REST API in the browser

Addresses that name things, methods that act

REST (Representational State Transfer) is a way to design a web API. Every address names a thing, and every method says what to do with it.

A well designed API is guessable. If you know /books lists the books, you can guess how to add one, change one and remove one.

By the end of this lesson

Note

I can design resource addresses and pick the right method for each job.

Key words

WordWhat it meansExample
Resourcea thing an API keeps, such as one book
Collectiona list of resources of one kind/books
Endpointthe address of a resource or a collection/books/7
Idempotentsending it twice leaves the same result as once
Query stringthe part of an address after ? that narrows a list?year=2004

The cells students fill in are left blank in this preview.

An address names a thing, never an action

A REST address is a noun. The resource is the thing, and the method is the verb. So /books is the collection of books and /books/7 is book number 7.

Do not put the action in the address. /getBooks and /deleteBook?id=7 repeat what the method already says. Use the plural for a collection, and nest a thing that belongs to another: /books/7/loans.

Worked example: weak addresses and better ones

Weak addressProblemBetter address
/getBooksThe verb is in the addressGET /books
/book/7/deleteThe action is in the addressDELETE /books/7
/Books_ListOdd capitals and a made-up name/books
/loans?book=7Fine for a filter, weak for ownership/books/7/loans

The cells students fill in are left blank in this preview.

Each method has one job

GET reads. POST adds a new resource and the server picks its id. PUT replaces a whole resource at a known address. PATCH changes some fields. DELETE removes.

A method is idempotent if sending it twice leaves the same result as sending it once. Idempotence matters because a network can fail after the server acted, so a client must know which requests are safe to repeat.

Worked example: the five methods compared

MethodJobChanges dataIdempotent
GETReadNoYes
POSTAdd a new oneYesNo: twice makes two
PUTReplace the whole thingYesYes
PATCHChange some fieldsYesUsually, when it sets a value
DELETERemoveYesYes

The cells students fill in are left blank in this preview.

Try the methods on a small catalogue

This lab's API is PostgREST. It names one row with a filter, so book 1 is /books?id=eq.1 where a classic REST API writes /books/1. The ideas are the same.

Run the next two commands to make a books table with three rows. Then each Run prints only the status code.

Give psql the password

Command
export PGPASSWORD=shop

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Make the books table

Command
psql -h db -U shop -c "drop table if exists books; create table books (id serial primary key, title text not null, year int not null, available boolean not null default true); insert into books (title, year, available) values ('Maps of the Sea', 1998, true), ('Rivers of Europe', 2004, false), ('Night Trains', 2011, true); notify pgrst, 'reload schema'"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

POST adds a book

Command
curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Content-Type: application/json" -d '{"title":"Tide Tables","year":2019}' "http://api:3000/books"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

PATCH marks book 1 as out

Command
curl -s -o /dev/null -w "%{http_code}\n" -X PATCH -H "Content-Type: application/json" -d '{"available":false}' "http://api:3000/books?id=eq.1"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Send the same PATCH again

Command
curl -s -o /dev/null -w "%{http_code}\n" -X PATCH -H "Content-Type: application/json" -d '{"available":false}' "http://api:3000/books?id=eq.1"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think POST and PUT do the same job because both send data. They do not. POST adds a new resource and the server chooses its id, so repeating it makes a second one. PUT puts a whole resource at an address you name, so repeating it changes nothing.

A query string narrows a collection

Filtering, sorting and paging are not new resources. They narrow a collection, so they go in the query string: the part after the ?.

Write /books?year=2004 and not /books/2004, which looks like one book. In this lab the same idea is ?available=eq.true, and & joins two conditions.

Titles of the books on the shelf

Command
curl -s -w "\n" "http://api:3000/books?available=eq.true&select=title&order=id"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

About this lab and its source: PostgreSQL and PostgREST lab: a database and a REST API in the browser

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.