Getting started with REST APIs

illustrations illustrations illustrations illustrations illustrations illustrations illustrations
post-thumb

Published on 29 September 2022 by Andrew Owen (7 minutes)

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 shouldn’t 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 doesn’t 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 don’t 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 is a common choice with good tools support. If you don’t have a schema, you can create one by building a Postman 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.

You can call a REST API from the command line using curl. For example:

curl -H "Authorization: Basic dXNlckBleGFtcGxlLmNvbTphY2Nlc3NfdG9rZW4=" \
     -H "Accept: application/json" \
     -H "Content-Type: application/json" \
     -X POST \
     -d '{"element":"value"}' \
     https://www.example.com/api/v2/endpoint/

With basic authorization, you pass a username:password string encoded in Base64. This is typically an email address and an authentication token. The backslash ( \ ) simply enables you to split the command across multiple lines. The content is made up of headers (-H), a method (-X), JSON data (-d) if required, and the endpoint URL. It should go without saying, but don’t put scripts containing authentication details in public repositories.

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 isn’t 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 an XML-based CCMS 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)
  • BrandOwnbrand (too generic to be registered as a trademark)
  • CountryUSA (ISO 3166-1 alpha-3 format)
  • Credit card number4111111111111111 (Use any CVV, NAME and future EXPIRY DATE. Keep purchase value under $500. https://docs.stripe.com/testing)
  • CurrencyUSD (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, use long version to avoid ambiguity)
  • Debit card number6304000000000000 (bank card number with the defunct Laser identifier)
  • Emailusername@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.
  • GUID01234567-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)
  • URLwww.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 wasn’t valid or can’t 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 isn’t valid, or the requested resource doesn’t exist.
  • 405 — Method not allowed: The requested resource doesn’t 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 can’t be satisfied.
  • 417 — Expectation failed.
  • 418 — I’m a teapot (don’t ask).
  • 421 — Misdirected request.
  • 422 — Entity can’t be processed: The request was well-formed, but the data couldn’t 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.