Thoughts on API Guidelines

Introduction

Within a few large Enterprises that I have had the chance to work at, below are my general thoughts and heavily swagger-influenced take on a good API.

This post will change over time. Last updated 01/24/20.

Overview

APIs are sets of requirements that govern how one application can communicate and interact with another. APIs may be used by both developers inside the organization that published the API or by any developers outside that organization who wish to register for access to the interface.

Some of the keys to a successful API are an Interface-first design, discoverability, reuse, engagement, and monitoring.

The quickest way to get running with a successful API is to understand the OpenAPI Specification - also known as the Swagger Specification. It is a specification for machine-readable interface files for describing, producing, consuming, and visualizing RESTful web services. The OpenAPI specification along with related tools can generate code for both clients and servers, documentation and test cases given an interface or ‘specification’ file.

REST

Representational state transfer

REST is a style, not a standard Like other web services, REST uses HTTP as the transport protocol for the message requests and responses. However, unlike other web services (e.g. SOAP), REST is an architectural style, not a standard protocol. This is why REST APIs are sometimes called RESTful APIs — REST is a general style that the API follows.

A RESTful API might not follow all of the official characteristics of REST as outlined by Dr. Roy Fielding, who first described the model. Hence these APIs are “RESTful” or “REST-like.” (Some developers insist on using the term “RESTful” when the API doesn’t fulfill all the characteristics of REST, but most people just refer to them as “REST APIs” regardless.)

REST Architectural Constraints

Client-server

The client application and server application must be able to evolve separately without any dependency on each other. A client should know only resource URIs and that’s all.

Stateless

Inspired from HTTP - make all client-server interaction stateless. Server will not store anything about latest HTTP request client made. It will treat each and every request as new. No session, no history. Though depending on the security scheme chosen some caveats to state will be accepted. Client is responsible for state, each request from the client should contain all the information necessary to service the request – including authentication and authorization details.

Cacheable

Caching brings performance improvement for client side, and better scope for scalability for a server because the load has reduced. Caching shall be applied to resources when applicable and then these resources declare themselves cacheable. Caching can be implemented on the server or client side.

Layered system

REST allows you to use a layered system architecture where you deploy the APIs on server A, and store data on server B and authenticate requests in Server C, for example. A client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way.

Uniform interface

As the constraint name itself applies, you must decide APIs interface for resources inside the system which are exposed to API consumers and follow religiously. A resource in the system should have only one logical URI and that should provide a way to fetch related or additional data. This leads to the emphasis on interface-first design principles.

Code on demand (optional)

Most of the time you will be sending the static representations of resources in form of XML or JSON. Optionally you are free to return executable code to support a part of your application e.g. to get a UI widget rendering code.

REST Architectural Elements

Data ElementModern Web Examples
resourcethe intended conceptual target of a hypertext reference
resource identifierURL, URN
representationHTML document, JPEG image
representation metadatamedia type, last-modified time
resource metadatasource link, alternates
control dataif-modified-since, cache-control

RESTful Web Service

Another unique aspect of REST is that REST APIs focus on resources (that is, things, rather than actions) and ways to access the resources. Resources are typically different types of information. You access the resources through URLs (Uniform Resource Locators), just like going to a URL in your browser retrieves an information resource. The URLs are accompanied by a method that specifies how you want to interact with the resource.

URL and HTTP methods

Resource Collection

http://api.example.com/resources/

ActionResults
GETList of collection’s members
PUTReplace the entire collection with another collection.
POSTCreate a new entry in the collection.
DELETEDelete the entire collection.

Resource Element

http://api.example.com/resources/17

ActionResults
GETRetrieve a representation of the addressed member of the collection.
PUTReplace the addressed member of the collection, or if it does not exist, create it.
POSTNot generally used. Treat the addressed member as a collection in its own right and create a new entry within it.
DELETEDelete the addressed member of the collection

OpenAPI

OpenAPI is API description language which is focusing on creating, evolving and promoting vendor neutral description format

You can write your API spec with OpenAPI

The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.

An OpenAPI definition can then be used by documentation generation tools to display the API, code generation tools to generate servers and clients in various programming languages, testing tools, and many other use cases.

What is OpenAPI

How to use OpenAPI

As API documents

Basic Structure

You can write OpenAPI definitions in YAML or JSON. A sample OpenAPI 3.0 definition written in YAML looks like:

openapi: 3.0.0
info:
  title: Sample API
  description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
  version: 0.1.9

servers:
  - url: http://api.example.com/v1
    description: Optional server description, e.g. Main (production) server
  - url: http://staging-api.example.com
    description: Optional server description, e.g. Internal staging server for testing

paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in CommonMark or HTML.
      responses:
        '200':    # status code
          description: A JSON array of user names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

The key components of the specification are: Metadata, Servers, Paths, Parameters, Request Body, Responses, Input/Output Models, and Authentication. The full OpenAPI 3.0 Specification is available on GitHub

With this specification you are then able to generate good looking documents, share API spec and iterate, develop independently frontend and backend or client and server, understandable with both developers and non-developers.

The Swagger organization in conjunction with the OpenAPI Specification has created API tools, these perform

As a quick background, some of the OpenAPI Competitors:

OpenAPI Tools

The tools that make the OpenAPI Specification powerful are:

Swagger Editor

Design, describe, and document your API on a open source editor fully dedicated to OpenAPI-based APIs. The Swagger Editor is great for quickly getting started with the OpenAPI specification, with support for Swagger 2.0 and OpenAPI 3.0.

It is a WYSIWYG Spec editor in web browser that provides syntax highlighting, autocompletion, and real time spec validation

CodeGen

Swagger Codegen can simplify your build process by generating server stubs and client SDKs for any API, defined with the OpenAPI specification, helping everyone focus on better API implementation and adoption.

Generating server stubs and client SDKs for any API.

Swagger UI

Swagger UI allows anyone, developers or consumers, to visualize and interact with the API’s resources without having any of the implementation logic in place. It’s automatically generated from the OpenAPI Specification, with the visual documentation making it easy for back end implementation and client side consumption.

OpenAPI Security

A security scheme definition is a global definition with a name that designates an authentication method available for the API. It is possible to define multiple schemes if, for example, an API supports both Basic Authentication and OAuth. There can even be various schemes of the same type.

A security requirement, on the other hand, can exist both globally for the entire API or on an operation level. It matches the API as a whole or the individual API operation to one or more of the previously defined security schemes. Developers can use this to specify different levels of authorization explicitly, for example, by making read requests available without authentication, but requiring OAuth for write requests.

OpenAPI lets you describe APIs protected using the following security schemes:

This example shows how various security schemes are defined. The BasicAuth, BearerAuth names and others are arbitrary names that will be used to refer to these definitions from other places in the spec.

components:
  securitySchemes:

    BasicAuth:
      type: http
      scheme: basic

    BearerAuth:
      type: http
      scheme: bearer

    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

    OpenID:
      type: openIdConnect
      openIdConnectUrl: https://example.com/.well-known/openid-configuration

    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://example.com/oauth/authorize
          tokenUrl: https://example.com/oauth/token
          scopes:
            read: Grants read access
            write: Grants write access
            admin: Grants access to admin operations

Asynchronous

Callbacks

In OpenAPI specs, you can define callbacks – asynchronous, out-of-band requests that your service will send to some other service in response to certain events. This helps you improve the workflow your API offers to clients. A typical example of a callback is a subscription functionality – users subscribe to certain events of your service and receive notification when this or that event occurs.

Walk through the spec:

callbacks are defined inside the related operation - post, put, and so on (not under the path itself). In this example, under the post method of the /subscribe path:

paths:
  /subscribe:
    post:
      
      callbacks:
        

API Management

API Management with an API Gateway is not required for a great API design, however they are helpful in platform implementation.

An API gateway is the single entry point for all clients. The API gateway handles requests in one of two ways. Some requests are simply proxied/routed to the appropriate service. It handles other requests by fanning out to multiple services. Rather than provide a one-size-fits-all style API, the API gateway can expose a different API for each client. Most of the times, the API gateway might also implement security, e.g. verify that the client is authorized to perform the request.

The API Gateway provides an extra layer in front of your API and can be managed by 3rd parties (externalized).

Features:

Examples technology providers:

These products typically take the OpenAPI Specification as the input to their platforms, being able to immediately consume and understand your backend.

API Versioning can be offloaded to the API Gateway, examples:

API Scalability can also be offloaded to the API Gateway:

Beyond HTTP/1.1

As technology evolves and new standards are implemented, some of the principles of a successful API remain: Interface-first design, discoverability, reuse, engagement, and monitoring.

One technology stack rising today is gRPC. gRPC, is an RPC framework based on protobufs and HTTP/2, that can make building and consuming APIs easier and more performant. As many clients speak http/1.1 plus json, the interoperability with JSON and Open API is very important. For users who are more comfortable with HTTP/1.1+JSON-based APIs and the Open API Initiative Specs APIs there are a combination of open source libraries to make gRPC services available in that form as well. There are a few groups that have built API multiplexers to give users the best of both worlds.

From CoreOS is an example of a gRPC + REST Gateway

Another great example is from the NYTimes with their openapi2proto.

Share this on → Twitter