By marone: September 2020 | last update: September 2020

Design REST API with openapi specification

Goal

In this article we want to design a REST API using OpenAPI specification.

What is openapi specification

An OpenAPI Specification (OAS) is a machine and human-readable standard for describing, consuming, documenting and visualizing RESTful APIs.
Originally known as Swagger Specification, it can be written with either using json or yaml format.

The usage of OpenAPI Specification would bring some great benefits, such as:

Document structure

openapi: 3.0.3
info:
  title: tutorial.com API
  version: 1.0.0
paths:
  /tutorials:
    get:
      responses:
        '200':
          description: Returns of tutorial names
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string

A minimal openapi file written in YAML, it contains only the mandatory sections.
A valid version field is needed, the following version fields are supported:swagger: "2.0" and openapi: 3.0.x.
The info section contains API information: title and version are mandatory.

The paths part describes diffrent endpoints (paths), each path has operations (HTTP methods, such as GET, POST, PUT, ...etc). Each operation can describe following information:
In this example we define one path with one operation GET /tutorials, which returns a list of tutorial names.

Swagger Editor

Swagger Editor is an open-source text editor to design and describe APIs, during you write it validates and renders the output. So you can immediately see the documentation. The output of our minimal openapi looks now like:

swagger editor simple example

Lets design

Now we want to expand the previous openapi file and design an API with more operations.
We start to design the model

Schemas

components:
  schemas:
    tutorial:
      type: object
      properties:
        id:
          type: integer
          format: in64
        name:
          type: string
        author:
          type: string
    tutorials:
      type: array
      items:
        $ref: '#/components/schemas/tutorial'

There is one schema tutorial, which contains three properties, the tutorials part is an array representation of tutorial.

Request body

  requestBodies:
    tutorialBody:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/tutorial'

A requestBody must be defined for operations which take payloads such as POST or PUT

Paths and operations

Before starting with paths and operations we want to add tags, that will help us to group the operations
tags:
  - name: tutorial interface
    description: Tutorial API

paths:
  '/tutorials':
    get:
      tags: 
        - tutorial interface
      responses:
        '200':
          description: Returns tutorials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/tutorials'
    post:
      tags: 
        - tutorial interface
      requestBody:
        $ref: '#/components/requestBodies/tutorialBody'
      responses:
        "200":
          description: "Ok, tutorial successfuly saved"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/tutorial'
        "400":
          description: "something went wrong"
        default:
          description: "Unexpected error"
  '/tutorials/{id}':
    get:
      tags: 
        - tutorial interface
      parameters: 
        - in: path
          name: id
          required: true
          description: id of tutorial
          schema:
            type: integer
            format: int64
      responses:
        "200":
          description: "return tutorial with the specified id"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/tutorial'
        "404":
          description: "tutorial not found"
        default:
          description: "Unexpected error"
    delete:
      tags: 
        - tutorial interface    
      parameters: 
        - in: path
          name: id
          required: true
          description: id of tutorial
          schema:
            type: integer
            format: int64
      responses:
        "204":
          description: "tutorial was deleted successfully"
        "404":
          description: "tutorial not found"
        default:
          description: "Unexpected error"

The paths section contains two paths: /tutorialand /tutorials/{id} each path can have multiple operations, for example GET /tutorial to get all tutorials and POST/tutorial to create a new tutorial. Each operation must define responses and (requestbody in case of POST). The combination between the path and an HTTP method can make the operations unique.
The second path uses curly braces {} which indicates the url parameters.
swagger editor example

Conclusion

In this article we tried to write an easy and simple example about how to design a Rest API. As you can see you, describing the interface were straightforward without any need of a programming language know-how. The ecosystem of toolset around openapi are great. To simplify things, sections such as servers and securitySchemes and other stuff are not mention here.


References