Open13

prismを使ってSwaggerのモックサーバーを立てた

You-sakuYou-saku

ディレクトリ構成

.
├── docker-compose.yml
└── openapi.yml

ファイルの中身は下記の通り

You-sakuYou-saku
docker-compose.yml
version: '3.9'
services:
  prism:
    image: stoplight/prism:4
    command: 'mock -h 0.0.0.0 /tmp/openapi.yml'
    volumes:
      - ./openapi.yml:/tmp/openapi.yml:ro
    ports:
      - '4010:4010'
open.yml
openapi: 3.0.0

info:
  title: mock-server
  version: 1.0.0
servers: # base endpoint
  - url: http://localhost:80/api
    description: base endpoint.
components: # JWTの定義
  securitySchemes:
    bearerAuth: # arbitrary name for the security scheme
      type: http
      scheme: bearer
      bearerFormat: JWT
security: # JWTの設定
  - bearerAuth: []
paths:
  /users:
    post:
      summary: create new user.
      tags: 
        - user
      description: create new user resource.
      requestBody:
        required:
          true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: "you-saku"
                email:
                  type: string
                  example: "sample@example.com"
                password:
                  type: string
                  example: "password"
                age:
                  type: integer
                  example: 10
              required:
                - name
                - email
                - password
      responses:
        '201':
          description: success create new user.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ID:
                    type: integer
                    example: 2
                  name:
                    type: string
                    example: "you-saku"
                  email:
                    type: string
                    example: "sample@example.com"
                  password:
                    type: string
                    example: "password"
                  age:
                    type: integer
                    example: 10
                  CreatedAt:
                    type: string
                    format: date-time
                    example: "2023-03-25T11:58:24.906Z"
                  UpdatedAt:
                    type: string
                    format: date-time
                    example: "2023-03-25T11:58:24.906Z"
                  DeletedAt:
                    type: string
                    format: date-time
                    nullable: true
                    example: null
                  Todos: # TODO
                    type: array
                    nullable: true
                    example: null
  /users/{id}:
    get:
      summary: get a user.
      tags: 
        - user
      description: get a user.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
            minItems: 1
      responses:
        '200':
          description: success get a user.
          content:
            application/json:
              schema:
                  type: object
                  properties:
                    ID:
                      type: integer
                      example: 1
                    name:
                      type: string
                      example: "you-saku"
                    email:
                      type: string
                      example: "sample@example.com"
                    password:
                      type: string
                      example: "password"
                    age:
                      type: integer
                      example: 10
                    CreatedAt:
                      type: string
                      format: date-time
                      example: "2023-03-25T11:58:24.906Z"
                    UpdatedAt:
                      type: string
                      format: date-time
                      example: "2023-03-25T11:58:24.906Z"
                    DeletedAt:
                      type: string
                      format: date-time
                      nullable: true
                      example: null
                    Todos: # TODO
                      type: array
                      example: []
  /ok:
    get:
      summary: sample endpoint.
      security: [] 
      tags:
        - sample
      description: test.
      responses:
        '200':
          description: 「api」 word.
          content:
            application/json:
              schema: 
                type: string
                example: api
You-sakuYou-saku

コンテナの様子を見ると

prism_1 | [4:16:26 PM] ? [CLI] ? info POST http://0.0.0.0:4010/users

prism_1 | [4:16:26 PM] ? [CLI] ? info GET http://0.0.0.0:4010/users/784

prism_1 | [4:16:26 PM] ? [CLI] ? info GET http://0.0.0.0:4010/ok

prism_1 | [4:16:26 PM] ? [CLI] ? start Prism is listening on http://0.0.0.0:4010

うん。動いてる感じする

You-sakuYou-saku

curlを実行すると

$ curl --location --request GET 'http://0.0.0.0:4010/ok' \
--header 'Accept: application/json'

"api"
You-sakuYou-saku

ちなみにsecurityも反映されている
しかし、securityのトークンはなんでもよかったりするらしい

curl --location --request GET 'http://0.0.0.0:4010/users/784' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer sample'

{"ID":1,"name":"you-saku","email":"sample@example.com","password":"password","age":10,"CreatedAt":"2023-03-25T11:58:24.906Z","UpdatedAt":"2023-03-25T11:58:24.906Z","DeletedAt":null,"Todos":[]}

ちゃんとSwaggerで定義されたものが返ってきます

You-sakuYou-saku

swaggerを編集するとホットリロードしてくれるそうです

You-sakuYou-saku

これ元々のbasepathは引き継げないのかな?

servers: # base endpoint
  - url: http://localhost:80/api
    description: base endpoint.
You-sakuYou-saku

2023/04/27 現在だとできなそう

api/v1とかは引き継げない感じ(READMEのFAQに書いてあった)

Why am I getting 404 errors when I include my basePath?

OpenAPI v2.0 had a concept called "basePath", which was essentially part of the HTTP path the stuff after host name and protocol, and before query string. Unlike the paths in your paths object, this basePath was applied to every single URL, so Prism v2.x used to do the same. In OpenAPI v3.0 they merged the basePath concept in with the server.url, and Prism v3 has done the same.
We treat OAS2 host + basePath the same as OAS3 server.url, so we do not require them to go in the URL. If you have a base path of api/v1 and your path is defined as hello, then a request to http://localhost:4010/hello would work, but http://localhost:4010/api/v1/hello will fail. This confuses some, but the other way was confusing to others. Check the default output of Prism CLI to see what URLs you have available.

https://github.com/stoplightio/prism#-faqs

You-sakuYou-saku

実際にWebサーバーを立ててswagger-uiとかと組み合わせていきたい
「モックがあると開発スピードがあまり落ちないはずだ」勝手に思ってる