Learn what OAS (Open Api Specification) is and basics of Swagger?9 min read

WHY SHOULD YOU USE OAS?

There is a huge amount of APIs over the whole worldwide web.
And many of them are not documented as they should be. So, you might hit the wall if you want to know more about how some API works.
In my professional career, I did hit the wall numerous times.

I don’t blame developers as this is tedious work they/we should do.
But using OAS we are all able, not only developers but also the managers, as well anyone who is (non)technically involved into the project to create, the easy way, a great API with great documentation from the start.

One of the beauties of using Swagger(OAS), is that non-technical expert might create an API and together with technical experts might define API and generate a much of boilerplate code for developers.

That way we boost developers productivity. Paired with time management skill we create great results and a happy client = happy employer = happy employee.

Imagine you can try out the requests straight out of the documentation!? That would be or better to say, IS fun!

I won’t delve too much into Swagger tooling as there are already great documentations about it.

What I will do is go into what API is, give you basics of OAS (Open API Specification) so you don’t get overwhelmed when you get in touch with it.

After reading this post you can start right away using Swagger and OAS with good basics and principles on how OAS / Swagger works.

So, I will show you the basic building blocks of writing OAS file.
But first, let’s start with what API is!?

WHAT IS API?

It’s an acronym for Application Programming Interface.
API defines how two (or more) pieces of software talk to each other.

There are several types of APIs:

  • Web service APIs
  • Websocket APIs
  • Hardware APIs
  • OS APIs
  • Library based APIs
  • Class based APIs
  • Object remoting APIs

But in this text I’ll be covering strictly Web APIs, to be more precise, REST APIs. Since Web APIs are more than REST APIs, we have:

  • SOAP
  • XML-RPC
  • JSON-RPC
  • REST

SO WHAT IS REST?

REST stands for REpresentational State Transfer and is not a protocol like the ones listed above.
REST is a set of architectural principles. So the architecture is the thing which differentiates a REST service of the other services.

WHAT IS AN OAS DEFINITION FILE?

It’s a simple file defining everything you can do with a collection of request coming to your API as well as responses.

Each definition file contains:

  • Server location
  • Type of security
  • All requests used in API
  • Data send to API
  • Data retrieved of an API
  • Types of HTTP status codes returned

To make it visually and easier to understand, an API request is shown below:

QUICK INTRO TO YAML

PHP developers using Symfony probably already know what YAML is.
As they use it regularly to configure for example Symfony framework.
YAML (an acronym for YAML Aint Markup Language) is a structured data format just like JSON is. So it’s used for data, NOT CONTENT.

The benefit of YAML is that it minimizes characters (compared to JSON or XML). So it’s mostly used for configuration files. It is structured like a dictionary (key: value).
Hence space between “key:” and “value”. ie.:

firstName: Denis

Since you can get into hierarchical depth or levels, the way you indent is by “white space“. No “tab indent” available!

Example:

name:
  firstName: Denis
  lastName: Jakus

It’s less characters compared to JSON:

name: {
	"firstName": "Denis"
	"lastName": "Jakus"
}

Even more less than XML:

<name>
	<firstName>Denis</firstName>
	<lastName>Jakus</lastName>
</name>

In YAML types are determined from context:

name: Denis (string)
weight: 104.5 (float)
years: 38 (integer)
social_number: HR123456789 (string)

As you can see strings don’t need to be quoted (nor single nor double-quoted)!
You quote only if something might be interpreted as number or boolean.
Then you can use single or double-quotes.

How do you define the list?

Well, just use a dash (-) in front of an item, ie:

animals:
 - type: Lion
   name: Sahara
   description: Some description
   years_old: 5
   weight: 150.4
   
 - type: Tiger
   name: Awahara
   description: Some description
   years_old: 2
   weight: 90.7
   color: white

Since there are no quotation marks, how do we preserve lines and spaces?

We use special characters! Since we can use multiple characters I’ll state here only a few, most used ones:

  • | means that we preserve spaces and lines i.e.:
  • > fold new lines

Examples:

name: |
 Denis 
     Jakus
	 
	 
Outputs:  
Denis 
 Jakus


name: >
 Denis
   Jakus

Outputs:
Denis Jakus

When commenting we use “#”

name: Denis #This is my name

ADDITIONAL SPECIAL COMMAND

$ref special OAS key that indicates that the value is a reference to a structure somewhere in the part of a file.

HOW TO CREATE DEFINITION FILE?

If using ie this domain:

example.com
https://api.example.com/getlist

Then just create file named filename.yaml with contents like:

swagger: '2.0' #might be 3.0 as new version is available

info: # Document metadata
 version: "0.0.1"
 title: Example api service

host: api.example.com
basePath: /getlist
schemes:
 - https

HOW TO DEFINE REQUEST?

Each request has to have:

  • URL endpoint
  • HTTP method
  • Path params
  • Query params
  • Request body
  • Response

Example of an defined POST request taken from editor.swagger.io:

paths:
  /pet:
    post:
      tags:
      - "pet"
      summary: "Add a new pet to the store"
      description: ""
      operationId: "addPet"
      consumes:
      - "application/json"
      - "application/xml"
      produces:
      - "application/xml"
      - "application/json"
      parameters:
      - in: "body"
        name: "body"
        description: "Pet object that needs to be added to the store"
        required: true
        schema:
          $ref: "#/definitions/Pet"
      responses:
        405:
          description: "Invalid input"
      security:
      - petstore_auth:
        - "write:pets"
        - "read:pets"

WHAT IS SCHEMA?

The schema indicates the structure of the data we use.
It’s based on the JSON Schema Specification (http://json-schema.org/) and can be many levels.

We use schema to define what are the keys in key-value pairs and to define what type of data are values.

Steps to create SCHEMA:

  1. Create a key called definitions at the end of the file
  2. Add a level and give it the name from the $ref value
  3. Add a properties key
  4. For each top level element in the JSON, add a key of its name.
  5. Add a type key that says what type of data it is
  6. Add other keys(objects) for other data

Example:

definitions:
 newAnimal:
  properties:
   name:
    type: string
   species:
    type: string
   weight:
    type: number
   years_old:
    type: integer
   color:
    type: string
   habitat:
    type: object
	properties:
	 country: 
	  type: string
	 continent:
	  type: string
	 zooParkName:
	  type: string
	 isInZoo:
	  type: boolean

As you can see from the above picture, there might be a lot of indentation, so this is where $ref comes handy. So we can rewrite the above like this:

definitions:
 newAnimal:
  properties:
   name:
    type: string
   species:
    type: string
   weight:
    type: number
   years_old:
    type: integer
   color:
    type: string
   habitat:
    $ref: '#/definitions/home'

and then write “home” somewhere else in the file like this:

home:
 properties:
  country: 
   type: string
  continent:
   type: string
  zooParkName:
   type: string
  isInZoo:
   type: boolean

You can also add array like this:

definitions:
 newAnimal:
  properties:
   name:
    type: string
   species:
    type: string
   weight:
    type: number
   years_old:
    type: integer
   color:
    type: string
   habitat:
    $ref: '#/definitions/home'
   sibblings:
    type: array
    $ref: '#/definitions/sibbling

and then add sibbling somewhere else in the file:

sibbling:
 properties:
  id:
   type: integer
  name:
   type: string

Since many of the things in OAS is self-explanatory like required, response or request I’ll skip this and move to something very useful.

Imagine you have two objects one for request and the other for a response. They probably have a very similar structure. But they also might have the only one difference between them, like included “id”.

In that case, we use “AllOf“, i.e.:

animal:
 allOf:
  - $ref: '#/definitions/newAnimal'
  - properties: 
      id:
	   type: integer
	   

As you can see, this key “allOf” is pretty useful.

WHAT ABOUT SECURITY?

Since this may be a little more complex topic to write about, I’ll just sum it up. If you don’t need security, great! Nothing to do here.

But, if you do want to secure your API then you use it like this:

  1. define security definition
  2. add name of your definition
  3. add type of security
  4. add name of header or query parameter
  5. set in value to know if it’s coming from query or header

Example when using OAuth security:

securityDefinitions:
  petstore_auth:
    type: "oauth2"
    authorizationUrl: "http://petstore.swagger.io/oauth/dialog"
    flow: "implicit"
    scopes:
      write:pets: "modify pets in your account"
      read:pets: "read your pets"
  api_key:
    type: "apiKey"
    name: "api_key"
    in: "header"

The above example has a little more stuff I did not explain. Like authorizationUrl, flow, scopes. These are self-explanatory.

  • authorizationUrl – endpoint to do the authorization
  • flow – are scenarios an API client performs to get an access token from the authorization server (more at https://swagger.io/docs/specification/authentication/oauth2/)
  • scopes – access to specific resource

AND HOW DO I HANDLE ERRORS?

Errors are simply different responses. And they should include schema for every potential status code. You define error code and description. Additionally you add schema.

Example:

responses:
 200:
  description: Everything is okay
 401:
  description: Uh no, you can't go here
  schema:
   $ref: '#/definition/error'
   

CONTENT TYPES

They indicate format of the data in request and response body by using “Content-Type” header (i.e. application/json).

We use:

  1. consumes for requests
  2. produces for responses

Example:

consumes:
 - application/json
 - application/xml
produces:
 - application/xml
 - application/json

SWAGGER TOOLING?

We got several tools by Swagger:

  1. Swagger Editor
  2. Swagger CodeGen
  3. Swagger UI
  4. Swagger Hub

SWAGGER EDITOR

Helps when creating OAS file (syntax checking, autogenerated documentation visible instantly…).

SWAGGER CODEGEN

Builds client SDKs based on OAS definition, does bunch of boilerplate code out of the box. Can generate a code for lot of known frameworks (Angular, React, .NET…)

SWAGGER UI

Generates api documentation

SWAGGER HUB

Hosts all of these tools above on a single platform.
This is the only, Swagger, thing which is not open source.
So you got to pay for it!

CONSLUSION

I find Swagger pretty useful. We at hte company are using it for every project we start. So i recommend you to take a look at it!

ALTERNATIVES

There are alternatives to Swagger. But using Swagger inside my everyday work projects, I did not have any need to try out something differently.

If you did try and you do have better experience using other tools, please comment at LinkedIn or Twitter.

I hope you learned something new today!

Cheers.

Leave a Reply

Your email address will not be published. Required fields are marked *