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

Free lesson

API versioning and breaking changes

After this lesson: I can document an API and change it without breaking its users.

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

An API is a promise to its callers

API versioning is how a team changes a web API while the apps that already use it keep working. Once other people build on your API, every change is a risk to them.

You will learn to document an API, to tell a safe change from a breaking one, and to retire something slowly.

By the end of this lesson

Note

I can document an API and change it without breaking its users.

Key words

WordWhat it meansExample
Documentationa written description of what an API offers
Versiona numbered state of the API that clients can name/v2/books
Breaking changea change that makes an existing client fail
Backward compatibleold clients keep working after the change
Deprecationannouncing that something will be removed later

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

Good documentation lets developers start alone

Documentation is written once and read many times. For every endpoint it gives the same parts.

It gives the address and method, what the request needs, what the answer holds, the errors it can give, and one example you can copy. A machine-readable description, such as an OpenAPI file, lets tools build the pages and test the API for you.

Worked example: one endpoint documented

PartWhat it says
Address and methodPOST /books
NeedsA JSON body with title (text) and year (whole number)
Success201, and the new book
Errors400 for a bad field, 401 for no key, 409 for a duplicate id
Example{"title": "Tide Tables", "year": 2019}

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

Change the catalogue and watch a client

Run the next two commands to make a books table. Then you will change its shape, the way a team changes an API, and watch what a client sees.

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.

Add a new field, author

Command
psql -h db -U shop -c "alter table books add column author text; notify pgrst, 'reload schema'"

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

Read book 1 and see the new field

Command
curl -s -w "\n" "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.

Adding is usually safe and removing is not

A change is backward compatible if old clients keep working. Adding an optional field is, because a client ignores what it does not know.

A breaking change makes an old client fail. Removing a field, renaming it, changing its type, or newly requiring an input are all breaking.

Worked example: safe or breaking

ChangeBreaks old clients?Why
Add an optional field to an answerNoClients ignore the new field
Remove a field from an answerYesClients that read it fail
Rename a fieldYesIt is a removal and an addition
Change a number into textYesClients that add it up break
Make a new input requiredYesOld requests lack it
Add a new endpointNoNobody calls it yet

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

An old client asks for its fields

Command
curl -s -o /dev/null -w "%{http_code}\n" "http://api:3000/books?select=id,title,year"

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

Rename year to published

Command
psql -h db -U shop -c "alter table books rename column year to published; notify pgrst, 'reload schema'"

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

Run the old client again

Command
curl -s -o /dev/null -w "%{http_code}\n" "http://api:3000/books?select=id,title,year"

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 a bug fix cannot break anyone. It can. If a client relied on the old behaviour, such as an order of results, fixing it breaks that client. Treat any change to what an answer means as breaking, and say so before you ship it.

A version lets old and new coexist

When a breaking change is needed, publish it as a new version and keep the old one running. The version goes in the address, such as /v2/books, or in a header.

Deprecation is the slow exit. You announce the date, warn callers in the response, and only remove the old version after that date.

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.