Self testable API docs
Docs shouldn't lie!

zoran.antolovic@asynclabs.co

Zoran Antolovic

Thank you for voting this talk up!

Who am I?

  • Zoran Antolović (24)
  • Osijek / Varaždin / Zagreb
  • ~14 years in love with technology 
  • ~6 years making living from IT

The Talk

Idea / Approach / Concept

API - (RESTful) Web services

Open for suggestions and comments

joind.in/talk/945fc

World of APIs

  • ~70% of public APIs are RESTful
  • JSON > XML
  • Providing SDKs is reserved for big guys
  • We need docs

API Docs aren’t important?

blitz test

when I start using a 3rd-party lib and notice there is no documentation

http://thecodinglove.com/post/49933241299

Documenting APIs

  • Describing API usage
  • Boring and manual work
  • Standard?
  • Validation?

Problems

  • Inaccurate documentation
  • Inconsistent API behavior
Exception in thread "main" com.google.gson.JsonSyntaxException: 
java.lang.IllegalStateException: Expected a boolean but was NUMBER 
at line 1 column 59 path $.active

Options for documenting APIs

  • No docs at all :)
  • Requests / Responses (curl, description, ...)
  • Manually written (Sphinx, Apiary, ...)
  • Meta information (Javadoc, Swagger, RAML, ...)

Documenting API
on hackathons / small projects

"How can I do something with something?"
I already told you, path is … - No, you didn’t.
Here is curl request example ... - How do I use that?

 

You really want to have some docs.

Try. Fail. Repeat.

Shared document

  • Hand-written
  • Time consuming
  • Not interactive
  • Cannot be tested

Postman

  • Hard to maintain
  • Manual

API tests

...

I should teach my mobile developers to read and understand my API tests

I should teach my mobile developers to read and understand write API tests

Team leader’s facepalm.

For ultra-dumb ideas.

API tests == Docs?

<?php
$I = new ApiTester($scenario);
$I->wantTo('create a user via API');
$I->amHttpAuthenticated('service_user', '123456');
$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
$I->sendPOST('/users', ['name' => 'davert', 'email' => 'davert@codeception.com']);
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->seeResponseIsJson();
$I->seeResponseContains('{"result":"ok"}');

Readable?

Goal

Have API docs that are easy to write, understand,
update and test.

We want to

Describe API behavior in a standardized way

Generate API docs

Automatically detect mistakes in API docs

  • JSON Schema / JSON Hyper Schema
  • Lightweight endpoint specification format
  • Tool for generating HTML docs from specification
  • Run API tests and validate response against specification

JSON Schema / Hyper-Schema

JSON Schema - annotate and validate JSON documents.


JSON Hyper-schema - JSON Schema + links

http://json-schema.org

https://spacetelescope.github.io/understanding-json-schema/index.html

{
  "title": "Web Camp Talk",

  "type": "object",

  "properties": {

    "title": {
      "type": "string",
      "required": true
    },

    "speaker": {
      "type": "string",
      "required": true
    },

    "duration": {
      "description": "Duration in min",
      "type": "integer",
      "enum": [25, 45]
    }
  }
}
{
  "title": "Self-testable API docs",
  "speaker": "Zoran Antolovic"
}
{
  "title": "Self-testable API docs",
  "speaker": "Zoran Antolovic",
  "duration": 25
}
{
  "title": "Self-testable API docs",
  "speaker": "Zoran Antolovic",
  "duration": 25,
  "speakerEarsSize": "XXL"
}

Trikoder's Apidoc

  • Document (legacy) API with JSON Schema
  • Generate interactive docs
  • Validate docs with API tests

open source > building from scratch

Available tools

PRMD

https://github.com/interagent/prmd

JSON Schema HTML Documentation Generator

https://github.com/cloudflare/json-schema-docs-generator

Available tools

Swagger

http://swagger.io

Open API Initiative (OAI)

https://openapis.org

Available tools

RAML - RESTful API Modeling Language

http://raml.org

API Blueprint

https://apiblueprint.org

Design + Prototype + Document + Test

Available tools

RAML - RESTful API Modeling Language

RAML example

RAML example

#%RAML 0.8
---
title: Jukebox API
baseUri: http://jukebox.api.com
version: v1

RAML example

#%RAML 0.8
---
title: Jukebox API
baseUri: http://jukebox.api.com
version: v1


/songs
  get
  post

  /{songId}
    get

    /file-content
      get
      post

RAML example

/songs:

  description: Collection of available songs in Jukebox

  get:
    description: Get a list of songs based on the song title.
    
    queryParameters:
      
      songTitle:
        description: "The title of the song to search"
        required: true
        minLength: 3
        type: string
        example: "Nemoze Nam Niko Nista"

    responses:
      ...

RAML example

...

    responses:

      200:

        body:

          application/json:

            example:
              ...

            schema:
              ...

RAML example

...

    responses:

      200:

        body:

          application/json:

            example: |

                {
                  "songId": "550e8400-e29b-41d4-a716-446655440000",
                  "songTitle": "Get Lucky"
                }

            schema:
              ...

RAML example

    responses:
      200:
        body:
          application/json:
            example:
              ...
            schema: |
              {
                "type": "object",
                "$schema": "http://json-schema.org/draft-03/schema",
                "id": "http://jsonschema.net",
                "required": true,
                "properties": {
                  "songId": {
                    "type": "string",
                    "required": true,
                    "minLength": 36,
                    "maxLength": 36
                  },
                  "songTitle": {
                    "type": "string",
                    "required": true
                  }
              }
              ...

RAML example

  • Descriptions
  • Parameters
  • Headers
  • Schemas
  • Examples
  • References
  • ...

Self-testable?

Endpoints

Methods

Requests

Responses

What do we need?

Testing the API

iterate over defined endpoints
  iterate over defined endpoint methods
    construct request from example/schema
    send request and get response
    validate response against method response definition
    happiness++

Example: Abao

RAML testing tool

https://github.com/cybertk/abao

 

Example: Abao

  • Endpoint exists?
  • URL params are supported?
  • required query parameters are supported?
  • defined HTTP request headers are supported?
  • HTTP request body is supported?
  • HTTP response headers are supported?
  • HTTP response body is supported?
$ abao jukebox-api.raml


  GET /songs -> 200
    ✓ Validate response code and body

  POST /songs -> 200
    ✓ Validate response code only

  GET /songs/{songId} -> 200
    ✓ Validate response code only

  GET /songs/{songId} -> 404
    ✓ Validate response code only

  GET /songs/{songId}/file-content -> 200
    ✓ Validate response code only



  5 passing (15ms)

Limitations

Missing support for multiple request/response models on the same endpoint based on headers or query params

Thank you!

Ta-da!

Q&A 

Feedback pls joind.in/talk/945fc

 

www.asynclabs.co | www.itworkslocal.ly

zoran.antolovic@asynclabs.co

linkedin.com/in/antoloviczoran

twitter.com/zoran_antolovic

Made with Slides.com