paulgorman.org/technical

API Design and Use (with REST and JSON and JavaScript)


(2018)

JSON (JavaScript Object Notation), like XML, is used as a data interchange format. It used the syntax of JavaScript object, making it easy to consume by web pages, for example.

REST (Representational state transfer) is a manner of exchanging data. REST is stateless. REST services most run over HTTP (and HTTP is itself RESTful). With a RESTful web resource, requests made to a resource’s URI return JSON (or XML or HTML or whatever). RESTful operations include the HTTP verbs GET, POST, PUT, DELETE and so on.

API Design

How do we put our request into the URL? What’s part of the path, and what’s added as query parameters? Generally, path parameters identify a specific resource or resources, while query parameters sort or filter those resources.

Idempotence

(Not strictly API-related, but since we’re touching on HTTP methods, here’s a refresher.)

From the perspective of a RESTful service, an idempotent operation is one that clients can perform repeatedly with one result. That is, if a client repeatedly performs the same operation with the same parameters, idempotency guarantees that those multiple operation have same effect as a single operation.

Since the GET, HEAD, OPTIONS and TRACE methods only read, they’re naturally idempotent.

DELETE is idempotent (but beware the first DELETE returning a 200 and subsequent DELETE’s on the same record return 404).

PUT is idempotent. (PUT generally updates an existing record.)

POST is necessarily not idempotent. (POST generally creates a new record.) E.g., clicking a “buy item” button ten times may get you ten instances of the thing, and that’s not idempotent.

PATCH is not idempotent.

Example API’s

API Consumption with Browser JavaScript

Among the several ways to use API data from a web page, choose the browser’s JavaScript fetch API to consume JSON.

CORS

A web page freely embeds cross-origin images, stylesheets, and scripts, but by default the same-origin security policy forbids other cross-origin requests, like Ajax. What is an “origin”? An origin is defined as the combination of protocol (http), port (80), and host (www.example.com). Cross-Origin Resource Sharing (CORS) allows restricted resources to be requested from a different origin.

CORS allows more than pure same-origin requests, but is more secure than allowing all cross-origin requests. CORS describes new HTTP headers that let browsers and servers request remote URLs only when they have permission. The browser must support these headers and honor the restrictions they impose.

What is the point of CORS? Alice visits shady website X. Website X runs an ill-intentioned script that tries to exploit an API at Alice’s bank. The banks sees that website X is not an acceptable origin, and blocks the abuse. CORS protects the user.

For Ajax and HTTP methods that modify data (e.g., methods other than GET), the browser “preflights” the request by soliciting supported methods from the server with an HTTP OPTIONS request. Upon “approval” from the server, the browser sends the actual request with the actual HTTP request method. Servers also notify clients whether credentials, like cookies and HTTP auth, should accompany requests.

The OPTIONS request sent by the browser includes the origin of the web pages (e.g., “Origin: www.example.com”). The server replies to the browser with an ACAO header to allow or deny the origin (e.g., “Access-Control-Allow-Origin: http://www.example.com”). The server might reply with a wildcard ACAO header (“Access-Control-Allow-Origin: *”), but that’s only appropriate for completely public API’s.

Authorization and API Keys

How do we restrict access to a non-public API? API keys are common, with three methods often used to pass the key from client to server.