Skip to content

Latest commit

 

History

History
221 lines (172 loc) · 9.83 KB

0015-how-to-document-cnd-http-api.adoc

File metadata and controls

221 lines (172 loc) · 9.83 KB

How to document the cnd HTTP API

Note
Author: Lucas Soriano del Pino <[email protected]>
Date: 2019-08-29
Tracking issue: #1122

Context

We have no documentation for cnd’s HTTP API. Having it is a hard requirement if we want to cater to application developers. It should also be helpful for the team and for newcomers.

Research

We have no documentation for cnd’s HTTP API. Having it is a hard requirement if we want to cater to application developers. It should also be helpful for the team and for newcomers.

Which API specification approach should we use?

Options

  • Extremely popular (specification has over 15k stars on GitHub).

  • Great tooling.

  • APIs can be specified using either YAML or JSON.

  • "Winner" of API Description Wars.

  • Quite popular (specification has over 3k stars on GitHub).

  • APIs can be specified using YAML.

  • Lots of tooling.

  • Good for designing large numbers of APIs.

  • Company behind joined Open API Initiative in 2017.

  • Very popular (specification has over 7k stars on GitHub).

  • More accessible to newcomers to API description.

  • Targets human readability over machine readability.

  • Lots of tooling.

  • APIs can be specified using a description language on top of Markdown (conforms to GitHub Flavored Markdown).

  • Company behind joined Open API Initiative in 2016.

Roll our own
  • More flexible.

  • No tooling.

  • An example showing how it could look.

Recommendation

OpenAPI, because it appears to be the industry standard, and is compatible with the most tools. The better human readability of API Blueprint doesn’t seem all that important given that these specifications can be viewed using powerful tools such as ReDoc.

How would a developer validate its API usage against the specification?

Mock servers powered by tools such as Connexion or Prism. These tools take a HTTP API specification and simulate a server that responds to requests according to the specification. This comes for free as long as we use one of the API description languages introduced above.

How do we ensure that API specification and implementation are in sync?

Options

  • Online tool.

  • Quick, manual testing.

  • Can generate OpenAPI specifications from requests and responses.

  • Language-agnostic.

  • Works with both OpenAPI and API Blueprint.

  • Very popular (over 3k stars on GitHub).

  • Command line tool.

  • Takes API specification and makes requests to server based on that, reporting whether the responses match the documentation.

  • Example:

dredd cnd-http-api-description.yml http:https://localhost:<port-where-cnd-is-hosted>
  • Works with Chai (which is compatible with Jest).

  • Easy to incorporate to our api tests workflow.

  • Example from GitHub repository:

// Set up Chai
const chai = require('chai');
const expect = chai.expect;

// Import this plugin
const chaiResponseValidator = require('chai-openapi-response-validator');

// Load an OpenAPI file (YAML or JSON) into this plugin
chai.use(chaiResponseValidator('path/to/openapi.yml'));

// Write your test (e.g. using Mocha)
describe('GET /example/request', function() {
  it('should satisfy OpenAPI spec', async function() {

    // Get an HTTP response using chai-http
    chai.use(require('chai-http'));
    const app = require('path/to/app');
    const res = chai.request(app).get('/example/request');

    expect(res.status).to.equal(200);

    // Assert that the HTTP response satisfies the OpenAPI spec
    expect(res).to.satisfyApiSpec;
  });
});

Recommendation

Dredd, because it’s well documented and has all the features we need. It looks like the main effort will be preparing the specification for testing.

JSON Schema integration

We currently use JSON Schema to validate the shape of the body of the response to GET / swaps and GET / swaps/rfc003/:id. JSON Schema is supported by OpenAPI, with some caveats. There are ways to get around this situation, and full support for JSON Schema is in the works.

How to generate the specification

Options

Automatically
Manually
  • Use Swagger Editor (over 5k stars on GitHub).

  • Use a plugin for an editor/IDE (look at the editors listed here).

Assisted
  • Using Swagger Inspector.

  • Make API calls to a running cnd through the UI and generate part of the specification.

Recommendation

Unfortunately the tools aren’t there yet to automatically produce the API specification from source code in Rust. There seems to be some interest for this, so it may come in the future. For the time being, we will have to write it ourselves. Fortunately, this specification will be tested and we can use tools such as speccy to validate it.

How to visualise specification

Options

  • Extremely popular (over 15k stars on GitHub)

  • RPC-style.

  • Looks like this: image::How_to_visualise_documentation/Swagger_UI_2019-08-29_18-16-23.png[scaledwidth=100%]

  • Hides JSON bodies.

  • Popular (over 1k stars on GitHub).

  • Very simple to set up.

  • Three-column style.

  • It looks very good: image::How_to_visualise_documentation/redoc-demo_2019-08-29_18-29-34.png[scaledwidth=100%]

  • Quite popular (about 1k stars on GitHub).

  • Looks similar to ReDoc: image::How_to_visualise_documentation/screenshot_2019-08-29_18-46-24.jpg[scaledwidth=100%]

Recommendation

ReDoc because it is easy and I think it looks nice.

What does the documentation include?

HTTP API Specification.

Models services.

JSON Schema.

Models data.

How to host documentation for current master HEAD

If we go for the recommended option of using ReDoc, it’s very easy:

  1. Include API specification in repository with cnd.

  2. Host a website on GitHub Pages (for example).

  3. Use a HTML tag that links to the API specification (there’s even a React component).

I would argue that this is covered in the original issue. Just replace human-protocol-spec key with a link to a static HTML page hosted on GitHub Pages (for example) where the meaning of human-protocol-spec is described.

Client-side validation

Context

  • We already define JSON Schemas for some data objects returned from the API.

  • We have discussed doing input validation on comit-i.

  • We currently reproduce server-side validation on comit-i.

Purpose

  • Improve user experience for users of clients of our API.

  • Simplify the job of developers.

Proposal

  • Define JSON Schemas for all data objects that our API returns.

  • Offer a copy of these contracts to clients in a programmatically accessible format.

  • Include link to in response header:

Link: <http:https://example.com/schemas/swap.schema.json#>; rel=”describedby”
  • Use in comit-i to prove that it works.