A first OpenAPI Contract! - OpenAPI [3]
Tags: api, productivity
Published: 2022-01-25 18:58:38

Today we will see together a simple OpenAPI contract and we will details each part.

First, here is the contract which we will use today.
```yaml
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
```
We can quickly see that we have some informations at the top related to the API and then the declaration of the only operation exposed.

---

## openapi
This variable is to defined the version of the specification used to write this contract.
At the moment where I'm writing this post, 4 versions are available
- 3.0.0
- 3.0.1
- 3.0.2
- 3.0.3

These versions are defined following the **[Semantic Versioning](https://semver.org/)** specifications. It's important to be aware of for a simple reason. Until the version stay at a 3.x.x version, you contract will works and you will be to continue with all the tools related to that version.
But if you are writing a contract with a 2.x.x specification version *(or when the specification will change to 4.x.x)*, your contract will may not work with 3.x.x tool due to a breaking change.

Currently all the OpenAPI stack fits for the 3.x.x version, so it will be ok. But just keep this information in mind.

*(you can check the post where I'm talking about semantic versioning {% post https://dev.to/adaendra/which-versioning-should-be-use-for-my-project-versioning-system-comparison-3h2k %})*

--- 

## info
This part contains metadata about the API. There are only 2 parameters which are mandatory : 
- **title**
- **version**. 

But the more you have informations in it, the best it will be for the support of the contract.

```yaml
title: Sample Pet Store App
description: This is a sample server for a pet store.
termsOfService: http://example.com/terms/
contact:
  name: API Support
  url: http://www.example.com/support
  email: support@example.com
license:
  name: Apache 2.0
  url: https://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.1
```

### Parameters 
|Field|Type|Description|
|---|---|---|
|title|string|Title of the API|
|description|string|Short description of the API|
|termsOfService|string|URL to the terms of service of the API|
|contact|object|To define a way to contact the person/team who supports the API|
|license|object|License information for the exposed API|
|version|string|Version of the API contract.|

---

## Servers
```yaml
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
```

This parameter will contain the list of all the endpoint available to use the API with a little description to understand the usage of this server *(development purposes only, production...)*.

---

## Paths
This part is a little bit more complex. Please open wide the next code to follow the comments to understand what's happening.

```yaml
paths: # Contains a list of paths
  /users:  # Example of a path
    get:  # Method which will be allowed for this path. Can be "put", "post", "delete"...
      summary: Returns a list of users. # Summary of the operation exposed for this path and this method.
      description: Optional extended description in CommonMark or HTML. # Longer description of the operation exposed.
      responses: # Responses that can be returned by the API
        '200':    # Status code of the response
          description: A JSON array of user names # Description of the response
          content: # Content of the response
            application/json: # File type of the response
              schema: # Schema to describe how the response is build.
                type: array # This response will be an array of strings.
                items: 
                  type: string
        '404':    # Other status code
          description: Not found # Description of the response without body.
```

We only see a little part of the **path** definition, but the objective in this part is to define all the paths/methods which are available to expose an operation.

Then for each operation, you will be able to define all the parameters *(optional or mandatory)* available :
- **headers**
- **query params**
- **body**

Also you will give all the informations about the responses you can give, to let you consumer know what can happen. 

So if you are interested to go further, please check the complete **OpenAPI specification** : https://swagger.io/specification/

---

I hope it will help you! 🍺