OpenAPI (Swagger) 入門

## はじめに
OpenAPIの仕様書の書き方についての備忘録です。

## OpenAPI
OpenAPIはREST　APIを記述するためのフォーマットです。
OpenAPI仕様に則って定義することでAPIのエンドポイント、パラメータ、レスポンス、認証方法などを記述することができます。

## Swagger
OpenAPIの設計や文書化のためのツールセットのこと。

## 書き方
基本的な書き方の説明です。
ymlは下記のような構造になっています。
```sample.yml
openapi: 
    ...

info:
    ...
    
servers:
    ...

paths:
    ...

components:
    ...
```

## 各オブジェクトの詳細
### info

```sample.yml
openapi: 3.0.3

info:
  title: Sample API # APIのタイトル
  description: This is a description of Sample API # APIについての説明
  termsOfService: http://www.example.com/terms/ # 利用規約のURL
  contact:
    name: API support
    url: http://www.example.com/support # 連絡先のURL
    email: support@example.com # 連絡先のemail
  version: 1.0.0 # APIドキュメントのバージョン
```

### servers

```sample.yml
servers:
  - url: http://localhost:3000 # 開発用サーバーURL
    description: 開発環境 # サーバーの説明
  - url: https://www.example.com/v1 # APIサーバーのURL
    description: 本番環境
```

Swagger UIで確認してみます。

![Sample servers](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338642/c6e264b9-2441-e8ee-bba2-b35ab59bc925.png)


ホストURLには変数を設定することもできます。
```sample.yml
servers:
  - url: https://{environment}.sample.com/v1 # 変数を含むサーバーURL
    description: API server
    variables: # 変数定義
      environment: # 変数の名前
        enum:
          - 'dev'
          - 'prod' # 変数に使用される文字列の配列
        default: 'dev' # 変数のデフォルト値
        description: 変数についての説明
```
これをSwagger　UIで表示してみます。

![Sample　variables](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338642/d162fa97-eca5-18a3-dbad-0ebca3795007.png)


### components
```sample.yml
components: # 再利用可能なオブジェクトを定義
  schemas:
    Error: # スキーマ定義
      type: object
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string
    Category:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
  parameters:
    skipParam:
      name: skip
      in: query
      description: number of items to skip
      required: true
      schema:
        type: integer
        format: int32
    limitParam:
      name: limit
      in: query
      description: max records to return
      required: true
      schema:
        type: integer
        format: int32
  responses:
    NotFound:
      description: Entity not found.
    IllegalInput:
      description: Illegal input for operation.
    GeneralError:
      description: General Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error' # componentsオブジェクトの参照先
  securitySchemes:
    api_key:
      type: apiKey
      name: api_key
      in: header
    petstore_auth:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: http://example.org/api/oauth/dialog
          scopes:
            write:pets: modify pets in your account
            read:pets: read your pets
```

### paths
```sample.yml
paths:
  /pets:
    get:
      description: Returns all pets from the system that the user has access to
      responses:
        '200':
          description: A list of pets.
          content:
            application/json:
              schema:
                type: array
                items:
                $ref: '#/components/schemas/Category'


```

![Sample　paths](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338642/f3077bbb-fcec-55a8-5a98-58724e069864.png)