3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenAPI に複数のレスポンス例を書いて、prism で mock API を立ててレスポンスを切り替えると便利

Last updated at Posted at 2024-07-05

はじめに

OpenAPI に複数のレスポンス例を書いて、prism で mock API を立てて、レスポンスを切り替えながら GUI 開発をすると便利と実感したので共有します。

検証に使ったコードはこちらに置いてあります。

目次

OpenAPISpecificationの仕様

OpenAPI Specification は複数のレスポンス例を書くことができます。swagger UI を使えば複数のレスポンス例を切り替えて表示できます。

  • スクリーンショット 2024-07-05 9.01.53.png
  • スクリーンショット 2024-07-05 9.02.06.png

Prism の仕様

Prism は OpenAPI に沿った mock server を立ててくれるツールです。Prism は request header に Prefer を入れることで response 内容を切り替えてくれます。例えば、"Prefer: example=example1" と指定すると example1 の response body を返してくれます。また、"Prefer: code=500" と指定すると status code 500 に記載してある example の response body を返してくれます。

開発時に行うこと

  1. OpenAPI に欲しいケースのレスポンス例を複数追加します。
  2. Prism で mock server を立ち上げます。
  3. request header に Prefer を付けてレスポンスを切り替えます。
    • local動作確認でmockが欲しい場合は load balancer(Caddy) を経由して header を追加します。

以下は、mock API を直接叩いた場合と、load balancer(Caddy)で header を追加した場合のレスポンスが異なる例です:

$ curl http://localhost:4010/api/users -s | jq       
{
  "users": []
}

$ curl http://localhost:8000/api/users -s | jq
{
  "users": [
    {
      "id": 1,
      "name": "John Doe",
      "mailAddress": "john.doe@example.com"
    },
    {
      "id": 2,
      "name": "Jane Doe",
      "mailAddress": "jane.doe@example.com"
    }
  ]
}

用意したコード

Caddyfile

http://localhost:80 {
    # API の定義を記載 start

    @api_users_get {
        path /api/users
        method GET
    }
    # API の定義を記載 end

    # レスポンス切り替える対象を記載 start
    handle @api_users_get {
        reverse_proxy http://api-mock:4010 {
            header_up Prefer "example=ManyUserResponse"
        }
    }
    # レスポンス切り替える対象を記載 end

    handle {
        reverse_proxy http://api-mock:4010
    }
}

docker-compose.yaml

version: '3.9'

services:
  api-mock-proxy:
    image: caddy:2
    restart: always
    ports:
      - "8000:80"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
    depends_on:
      api-mock:
        condition: service_started

  api-mock:
    image: stoplight/prism:4
    ports:
      - "4010:4010"
    volumes:
      - ./openapi.yaml:/openapi.yaml
    command:
      mock /openapi.yaml -h 0.0.0.0 -p 4010

  swagger:
    image: swaggerapi/swagger-editor
    ports:
      - "8080:8080"
    volumes:
      - ./openapi.yaml:/openapi.yaml
    environment:
     - SWAGGER_FILE=/openapi.yaml

openapi.yaml

openapi: 3.0.3
info:
  title: User API
  version: 1.0.0
paths:
  /api/users:
    get:
      summary: Get list of users
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  users:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
              examples:
                emptyUsersResponse:
                  summary: No users
                  value:
                    users: []
                oneUserResponse:
                  summary: One user
                  value:
                    users:
                      - id: 1
                        name: John Doe
                        mailAddress: john.doe@example.com
                ManyUserResponse:
                  summary: Multiple users
                  value:
                    users:
                      - id: 1
                        name: John Doe
                        mailAddress: john.doe@example.com
                      - id: 2
                        name: Jane Doe
                        mailAddress: jane.doe@example.com
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
              example:
                error: Internal server error
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
          example: 1
        name:
          type: string
          example: John Doe
        mailAddress:
          type: string
          example: john.doe@example.com

考察

mswjs でレスポンスを変更してテストする方法もあるみたいです。しかし、本記事の方法だとOpenAPI定義書に複数のレスポンス例が書かれて良いです。

検証の元になった記事

最後に

最後までお読み頂きありがとうございます。励みになるので、良かったらいいね 👍 をお願い致します。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?