OpenAPIのチュートリアルまとめ

# OpenAPI tutorial

OpenAPIを触る機会があったが、初見だったため、公式サイトのチュートリアルを見てみました。
それのまとめです。

## 参考文献

https://support.smartbear.com/swaggerhub/docs/en/get-started/openapi-3-0-tutorial.html

https://qiita.com/koko_ko/items/3491200171a6cc6111be

https://swagger.io/docs/specification/describing-responses/?_ga=2.106048768.202973796.1699424381-307914148.1699424381

https://techblog.asahi-net.co.jp/entry/2019/03/04/102734#JSON-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88


## What is OpenAPI

- OpenAPI SpecificationとはAPIドキュメントを作成するためのオープンソースフォーマット
- RESTful APIをデザインするツールとして、幅広く使用されている
- JSONかYAML形式で記述する（YAMLの方が読みやすい,書きやすいでおすすめらしい）

## Create an API

レコードレーベルのためのAPIを作成する。
データベースで管理する情報は以下のとおり
- Artist name
- Artist genre
- Number of albums published under the label
- Aritist username

APIはOpenAPI Specificationによって3つのパートにわかれる。

- Meta information
- Path items (endpoints)
  - Parameters
  - Request bodies
  - Responses
- Reusable components:
  - Schemas (data models)
  - Parameters
  - Responses
  - Other components

## Meta information

APIのタイトル、バージョン、サーバーURLなどを記述する部分。

```yaml
openapi: 3.0.0 
info:
  version: 1.0.0 #必須項目
  title: Simple Artist API #必須項目
  description: A simple API to illustrate OpenAPI concepts #任意

servers:
  - url: https://example.io/v1
  # 複数サーバーの情報を記述することが可能（実装環境+テスト環境など）

# Basic authentication
# 限られたユーザーに提供するなど、セキュリティ情報を記述することが可能
components:
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
security:
  - BasicAuth: []
```

## Path items

エンドポイントを記述する部分。`servers` に記述したURLの相対パスとして記述。

レスポンスで返す、HTTPステータスとデータを記述できる。

```yaml
paths:
  /artists:
    # GET https://example.io/v1/artists
    get:
      description: Returns a list of artists 
      responses:
      '200':
        description: Successfully returned a list of artists
        content:
          application/json: #レスポンス形式を決定
            schema:
              type: array #データの型を宣言
              items:
                type: object
                required:
                  - username
                properties:
                  artist_name:
                    type: string
                  artist_genre:
                    type: string
                  artist_recoreded:
                    type: integer
                  username:
                    type: string

        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                type: object
                properties:   
                  message:
                    type: string
```

上の例では、以下のようなレスポンスデータが返ってくる。

```yaml
# 200
[
    {
        "artist_name": "hoge",
        "artist_genre": "foo",
        "artist_recoreded": 10,
        "username": "bar"
    }
]

# 400
{
    "message": "hogehoge"
}
```

200番の場合、`content` 直下の `application/json` でjson形式のレスポンス型を指定。`schema` の下の `array` で配列型のデータを作り、配列内のデータとして `object` を作成している。

`array`　の場合は `items`、`object` の場合は `properties` で要素を記述できる。


## Parameters

```yaml
paths:
  /aritists:
    get:
      # queryパラメータ
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
    
    post:
      # リクエストボディ
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                aritist_name:
                  type: string
    
  /aritists/{username}:
    get:
      # pathパラメータ
    　parameters:
      　- name: username
       　 in: path
       　 schema:
         　 type: string
```

## Reusable components

OpenAPIでは、変数のように繰り返し使うことのできるコンポーネントを記述することが可能である。


```yaml
components:
  schemas:
    Artist:
      type: object
      required: 
        - username
      properties:
        artist_name:
          type: string
        artist_genre:
          type: string
        artist_recorded:
          type: integer
        username:
          type: string
  
  parameters:
    PageLimit:
      name: limit
      in: query
      schema:
        type: integer
  
  responses:
    400Error:
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
```

呼び出すときは以下のように記述する。

```yaml

paths:
  /artists:
    get:
      parameters:
        - $ref: '#/components/parameters/PageLimit'
      responses:
        200:
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Artist'
        400:
          $ref: '#/components/responses/400Error'
```