Getting started with REST APIs
Tags: rest, api, webdev, documentation
Published: 2022-12-19 18:06:33

> This article originally appeared on my personal dev blog: [Byte High, No Limit](https://andrewowen.net/blog/).

REST (representational state transfer) APIs (application programming interfaces) have been around since the turn of the century, when they were defined by Dr. Roy Fielding in his doctoral dissertation. Since then, they have become the main method for connecting the components in microservices architectures.

Among other things, web APIs enable a client application to interact with a service running on a server. Unlike earlier solutions like SOAP and XML-RPC, REST gives developers a lot more flexibility. For example, you can use whatever language or data format you like. Although in practice, JavaScript and JSON are often the preferred choices.

The goals of REST are:

* Components that are _portable_ and can be _modified_.
* Maximum _scalability_.
* _Performance_ of interactions.
* _Reliability_ (a component failure should not take down the whole system).
* _Simple_ user interfaces.
* _Visible_ communications

It has six design principles:

* **Cachebility**. For server-side scalability and client-side performance, responses must be defined as cacheable or non-cacheable. Cache can be stored in a CDN (content delivery network). The aim is to reduce the number of client-server interactions.
* **Code on demand** (optional). Responses can contain executable code (typically JavaScript). This enables the server to extend the functionality of the client.
* **Client-server decoupling**. The client can only interact with the server using a uniform resource identifier (URI). The server can only interact with the client by responding to the request using HTTP. This makes it possible to completely replace the client application without making any changes to the server.
* **Layered system architecture**. It does not matter if the client is connected directly to the server or through an intermediary. This is good for load balancing and enables the use of a security layer, separating business and security logic.
* **Statelessness**. No session information is required or retained by the server. This absence of server sessions enables rapid processing of high volume data.
* **Uniform interface**. Resources are identified by URI. The client manipulates a representation of the resource, including any metadata. Messages self-describe how they should be processed. The client dynamically discovers resources from the original URI, without the need for hard-coding.

You may encounter APIs described as RESTful that do not meet these criteria. This is often the result of bottom-up coding, where top-down design should have been used. Another thing to watch out for is the absence of a schema. There are alternatives, but [OpenAPI](https://github.com/OAI/OpenAPI-Specification/tree/main/versions) is a common choice with good tools support. If you don't have a schema, you can create one by building a [Postman](https://www.postman.com/) collection.

Typically, REST APIs use only the four most common HTTP methods:

| Method | CRUD | Typical response code |
| --- | --- | --- |
| POST | Create | 201 Created |
| GET | Read | 200 Success |
| PUT | Update | 202 Accepted |
| DELETE | Delete | 204 No Content |

For reference, the full set of HTTP methods is:

* DELETE — Deletes the specified resource.
* GET — Request data from a specified resource.
* HEAD — Almost identical to GET, but without the response body.
* OPTIONS — Describes the communication options for the target resource.
* PATCH — Applies partial modifications to a resource.
* POST — Send data to a server to create a resource.
* PUT — Send data to a server to create or update a resource.

#### Documentation

When I became an API writer I found that, just like other software, docs are often an afterthought. But if you want people to use your APIs, they need to be well documented. However, API writing is not the same as traditional technical writing. Use a terse, factual writing style. Sentence fragments are desirable. Avoid adjectives and adverbs. You need to provide:

* Complete information about each API component.
* Contact details in case developers have questions or require additional assistance.
* Flow charts showing the sequence of the most commonly used methods for common use cases.
* Getting Started guides showing how to develop a program for a common use cases.
* Performance and tuning information.
* Sample programs demonstrating common use cases.
* Working code snippets for each method, function, and resource. You don’t need complete examples, but show a common use of that element.

#### Boilerplate text

One of the limitations of the current generation of Markdown and API doc tools is that they have little to no support for automated content reuse (which is why I recommend [Paligo](https://paligo.net/ "Paligo") for docs). For that reason, you should keep a list of standard definitions and valid payload examples. For example:

* _Address_ — Use your company's main address.
* _Barcode_ — 019000000002 (UPC-A format including check digit)
* _Brand_ — _Ownbrand_ (too generic to be registered as a trademark)
* _Country_ — _USA_ (ISO 3166-1 alpha-3 format)
* _Credit card number_ — _4111111111111111_ (Use any CVV, NAME and future EXPIRY DATE. Keep purchase value under $500. [http://testcreditcardnumbers.com/](http://testcreditcardnumbers.com/ "http://testcreditcardnumbers.com/"))
* _Currency_ — _USD_ ([https://www.iso.org/iso-4217-currency-codes.html](https://www.iso.org/iso-4217-currency-codes.html "https://www.iso.org/iso-4217-currency-codes.html"))
* _Date time offset_ — 2019-11-01T00:00:00-05:00 ([https://en.wikipedia.org/wiki/ISO_8601](https://en.wikipedia.org/wiki/ISO_8601 "https://en.wikipedia.org/wiki/ISO_8601"), use long version to avoid ambiguity)
* _Debit card number_ — _6304000000000000_ (bank card number with the defunct Laser identifier)
* _Email_ — _username@example.com_ (example.com is reserved for examples)
* _First name_ — Don't use other terms for first name. In some cultures, the family name precedes the given name.
* _GUID_ — _01234567-890a-bcde-f012-34567890abcd_
* _Last name_ — Don't use other terms for last name. In some cultures, the family name precedes the given name.
* _Telephone_  — _+1 202 555 0199_ (555 numbers ending 0100-0199 are fictitious)
* _URL_ — _www.example.com_ (example.com is reserved for documentation)

#### HTTP response codes

You should provide as much response code information as possible. The minimum acceptable level of documentation is the number, a meaningful short description and an explanation for typical use cases.

###### 1xx: information

* 100 — Continue.
* 101 — Switching protocols.
* 102 — Processing.
* 103 — Early hints.

###### 2xx: success

* 200 — Success: Object created.
* 201 — Created: Object created or replaced.
* 202 — Accepted: Processing asynchronous request.
* 203 — Non-authoritative Information.
* 204 — No content.
* 205 — Reset content.
* 206 — Partial content.
* 207 — Multi-status.
* 208 — Already reported.
* 226 — Instance-manipulations used.

###### 3xx: redirection

* 300 — Multiple choices.
* 301 — Moved permanently.
* 302 — Found.
* 303 — See other.
* 304 — Not modified.
* 305 — Use proxy.
* 306 — Switch proxy.
* 307 — Temporary redirect.
* 308 — Permanent redirect.

###### 4xx: client errors

* 400 — Bad request: The request was not valid or cannot be otherwise served. Typical when there is a syntax error in the request. Further details of the error are provided in the response payload body.
* 401 — Unauthorized: Missing or incorrect authentication credentials.
* 402 — Payment required.
* 403 — Forbidden: The request is understood, but it was refused or access was denied. The response payload body provides further details of the error.
* 404 — Not found: The URI is not valid, or the requested resource does not exist.
* 405 — Method not allowed: The requested resource does not support the method.
* 406 — Not acceptable.
* 407 — Proxy authentication required.
* 408 — Request timeout.
* 409 — Conflict.
* 410 — Gone.
* 411 — Length required.
* 412 — Precondition failed.
* 413 — Payload too large: The request is larger than the server is able to process.
* 414 — URI too long.
* 415 — Unsupported media type.
* 416 — Range cannot be satisfied.
* 417 — Expectation failed.
* 418 — I'm a teapot (don't ask).
* 421 — Misdirected request.
* 422 — Entity cannot be processed: The request was well-formed, but the data could not be processed due to semantic errors.
* 423 — Locked.
* 424 — Failed dependency.
* 425 — Too early.
* 426 — Upgrade required.
* 428 — Precondition required.
* 429 — Too many requests.
* 431 — Request header fields too large.
* 451 — Unavailable for legal reasons.

###### 5xx: server errors

* 500 — Internal server error: This is usually a temporary error, for example in a high load situation or if an endpoint is temporarily having issues.
* 501 — Not implemented.
* 502 — Bad gateway.
* 503 — Service unavailable.
* 504 — Gateway timeout.
* 505 — HTTP version not supported.
* 506 — Variant also negotiates.
* 507 — Insufficient storage.
* 508 — Loop detected.
* 510 — Not extended.
* 511 — Network authentication required.

Image: Original by [Jalan Rayam](https://www.facebook.com/blogjalanrayamalaysia/ "Jalan Rayam").