Introduction

This is the initial draft of recommended best practices for API development and consumption at Columbia.

Overview

The central feature of REST architecture is the emphasis on a uniform interface between components

REST is defined by four interface constraints:

RESTful Application URL and methods

The Key principle of REST involves separating API into logical resources. These resources are manipulated using HTTP requests where the method (GET,POST,PUT,PATCH,DELETE) has specific meaning.

REST API resources are plural nouns (not verbs!) from the consumer perspective.

Versioning

Always version the API. There are two widely accepted approaches to versioning

  1. Version as part of URL

  2. Version as part of header

We at Columbia choose version to be part of URL:

Version should be kept to the right of the app name. We choose to prefix 'v' as part of version and use only the ordinal numbers, like “v1”, “v2”, etc.

API Pattern

Use the following example patterns as a guide. Implementing every HTTP method and complex search query parameters is not required but should follow these patterns when used.

Note that the above definitions have use the following query parameter names:

For more complete details, see the JSON API Architecture Pattern.

API Pattern Example

Basic Operation APIs are shown with examples (for the directory app, version 1):

Application Metadata Resources (DRAFT)

The following metadata and special resources should be available for every application:

Enterprise Metadata Resources (DRAFT)

A top-level Columbia University enterprise metadata directory will contain the list of available types (schemas) and resource types (item, collection, etc.) that are used by the various applications:

SSL Everywhere

Always use SSL, no exceptions. This is enforced at the f5 load balancer (https://<domain-app>.api.columbia.edu) which terminates SSL sessions.

Documentation

Always provide good API documentation. The document should be easy to find and publicly accessible to the consumers. Documentation should consist of:

JSON only responses

At Columbia JSON responses are preferred responses from API

Pagination

For APIs which returns large number of records, links should be used for pagination into the previous and next pages. For example:

{
  "links": {
    "first": "https://app.api.columbia.edu/v1/things/?page[number]=1",
    "last": "https://app.api.columbia.edu/v1/things/?page[number]=448",
    "next": "https://app.api.columbia.edu/v1/things/?page[number]=2",
    "prev": null
  },
  "data": [ ... ]
}

Rate Limiting

It is good practice to add rate limiting to an API, use HTTP status code 429 Too Many Requests

Some good example of rate limiting can be found here

Authentication

REST APIs are stateless. API request authentication shouldn't depend cookies and sessions. Instead each request should use some sort of token for authorization.

Tokens can be associated with two types of resources i.e. Applications and/or users of applications

oAuth2 will be used in Columbia to provide the secure token for API authorization.

oAuth2 Protocol


Caching

Use HTTP's inbuilt capability for caching, following can be used as part inbound request header

ETag : An ETag is an opaque identifier assigned by a web server to a specific version of a resource found at a URL. If the resource representation at that URL ever changes, a new and different ETag is assigned. Used in this manner ETags are similar to fingerprints, and they can be quickly compared to determine whether two representations of a resource are the same.

In typical usage, when a URL is retrieved the web server will return the resource's current representation along with its corresponding ETag value, which is placed in an HTTP response header “ETag” field:

   ETag: "686897696a7c876b7e"

The client may then decide to cache the representation, along with its ETag. Later, if the client wants to retrieve the same URL again, it will send its previously saved copy of the ETag along with the request in a “If-None-Match” field.

   If-None-Match: "686897696a7c876b7e"

On this subsequent request, the server may now compare the client's ETag with the ETag for the current version of the resource. If the ETag values match, meaning that the resource has not changed, then the server may send back a very short response with a HTTP 304 Not Modified status. The 304 status tells the client that its cached version is still good and that it should use that.

Last-Modified : This basically works like to ETag, except that it uses timestamps. The response header Last-Modified contains a timestamp, which is validated against If-Modified-Since.

Errors

An API should provide a useful error message in a known consumable format like JSON. The error message should contain its own set of fields, for example:

{
    "errors": [
        {
            "detail": "Authentication credentials were not provided.",
            "status": "401",
            "source": {
                "pointer": "/data"
            },
            "code": "not_authenticated"
        }
    ]
}

N.B. See JSON API error objects.

HTTP Codes

API should return HTTP defined status codes, which helps consumer of API route their responses accordingly, see below for the list (HTTP Status code)

References