Concepts / Automation and APIs

Automation and APIs

REST API

Also called API, CRUD, GET, POST, PUT, PATCH, DELETE, resource, endpoint, status code, RESTCONF, idempotent method

An HTTP interface where every thing is a URL and the methods are the verbs: GET reads, POST creates, PUT and PATCH change, DELETE removes.

Each resource has a URL (/api/routes/1); a collection (/api/routes) takes POST to create a member. The four CRUD operations map to methods: create POST, read GET, update PUT (the whole resource) or PATCH (some fields), delete DELETE. Each request is stateless: it carries its credentials and everything else the server needs. The status code says how it went: 200 OK, 201 Created (with a Location header), 204 No Content, 400 Bad Request, 401 not authenticated, 403 not allowed, 404 Not Found; 5xx means the server failed. GET, PUT and DELETE are idempotent (repeating one changes nothing more); POST is not. RESTCONF is the standard REST API for network devices, built on YANG data models.

How a REST API works, step by step

A REST API is an HTTP interface where every thing is a URL (a resource) and the methods are the verbs. Follow the REST API lab, where laptop drives a controller at 10.0.1.10:8080 that configures routers over SSH:

  1. Authenticate. A request to /api/ without credentials gets 401 and a WWW-Authenticate: Basic header. The client proves who it is: HTTP Basic (user:password base64 in the Authorization header on every request), a Bearer token it obtained once, or an X-API-Key header. See API authentication.
  2. Read a resource. GET /api/devices/edgeRouter returns a JSON object. Each request is stateless: it carries its own credentials and everything the server needs, so any server can answer it.
  3. Create. POST /api/routes with a JSON body creates a member of the collection. The reply is 201 Created with a Location header naming the new resource's URL.
  4. Change. PUT /api/routes/1 replaces the whole resource (missing fields reset); PATCH changes only the fields sent. Both return 200 with the updated object.
  5. Delete. DELETE /api/routes/1 removes it and returns 204 No Content; repeating it returns 404.

The status code says how it went: 2xx success, 400 bad request, 401 not authenticated, 403 not allowed, 404 not found, 5xx the server failed. GET, PUT and DELETE are idempotent (repeating changes nothing more); POST is not. RESTCONF is the standardised REST API for network devices, built on YANG models, and a network controller exposes one like this.

What it looks like on a Linux machine

A request with no credentials is refused; adding HTTP Basic lets it through:

$ curl -si http://10.0.1.10:8080/api/devices
HTTP/1.1 401 UNAUTHORIZED
WWW-Authenticate: Basic realm="controller"
{"error": "authentication required: HTTP Basic, a Bearer token or an X-API-Key header", "status": 401}
$ curl -s -u admin:netlab http://10.0.1.10:8080/api/devices
[{"name": "edgeRouter", "address": "10.0.1.2", "managedRoutes": 0}, {"name": "branchRouter", "address": "10.0.12.3", "managedRoutes": 0}]

jq parses the JSON reply; curl and jq together are the whole toolkit:

$ curl -s -u admin:netlab http://10.0.1.10:8080/api/devices/edgeRouter | jq -r '.interfaces[] | .network + " " + .addresses[0]'
office 10.0.1.2/24
transit 10.0.12.2/24

Creating a route returns 201 with a Location header, and the network changes:

$ curl -si -u admin:netlab -X POST -H 'Content-Type: application/json' \
    -d '{"device": "edgeRouter", "destination": "10.0.2.0/24", "via": "10.0.12.3"}' http://10.0.1.10:8080/api/routes
HTTP/1.1 201 CREATED
Location: /api/routes/1
{"id": 1, "device": "edgeRouter", "destination": "10.0.2.0/24", "via": "10.0.12.3", "description": "", "createdBy": "admin"}

A malformed body gets 400 with a reason; a read-only API key posting gets 403 this API key may only read; and DELETE returns HTTP/1.1 204 NO CONTENT with an empty body.

What goes wrong, and how you see it

401 you did not expect. The server returns 401 UNAUTHORIZED with WWW-Authenticate: Basic. Either no Authorization header was sent, or the Bearer token expired (the lab's tokens last an hour). Re-authenticate or fetch a new token.

403 not 401. The request authenticated but is not allowed: in the lab a read-only API key doing POST gets 403 this API key may only read. The fix is a credential with write permission, not a retry.

400 from a bad body. Posting without a required field returns 400 and a message like missing fields: via. Forgetting Content-Type: application/json can make the server parse the body as empty. Send valid JSON and the header.

PUT wiped a field. PUT replaces the whole resource, so a field left out reverts to its default (the lab's description empties). Use PATCH to change one field, PUT only to replace everything.

Questions people ask

What is the difference between PUT and PATCH? PUT replaces the entire resource, so the body must carry every field or the missing ones reset; PATCH merges only the fields you send. Both are used to change an existing resource; POST creates a new one.

What does idempotent mean? Repeating the request has no extra effect. GET, PUT and DELETE are idempotent: deleting twice still leaves the resource gone (the second returns 404). POST is not, so each POST creates another member.

Is REST the same as JSON? No. REST is the style (resources as URLs, HTTP verbs, stateless requests); JSON is just the common body format. The lab's controller also serves YAML and XML from the same data via the Accept header.

See it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Open this lab