如何使用 Swagger/OpenAPI Specification + Prism 建立基於合約的 Mock Server

在介接其他人寫的 Web API 時,可以透過 Mock Server 來模擬對方會回傳的資料,比如說 json-server,但這樣往往會因為兩造之間沒有一個合約、規範,各自實作,導致最後在整合的時落差太大;理論上,雙方基於合約、規範,進行開發,最後在整合的時候應該有問題的狀況應該會小一點,Prism 是套基於 Swagger/OpenAPI Specification 的 Mock Server,在 OpenAPI 的生態系裡面算是蠻完整的解決方案之一,接下來,是我對它在使用上的小小心得。

開發環境

下載官方的範例檔,檔名改成 index.yaml

安裝

npm install -g @stoplight/prism-cli

 

或是

docker run --init -p 4010:4010 stoplight/prism:4 mock -h 0.0.0.0 api.oas2.yml


 

建立 Mock Server

prism mock doc/1/index.yaml

執行結果,如下圖:

prism 模擬出可使用的資源,回傳值則是根據 Swagger/OpenAPI Spec

 

調用 Mock Server

curl 127.0.0.1:4010/pets

執行結果,如下圖:

 

可以發現這時候的回傳值是型別名字,不過,我更希望他回傳的是有意義的資料

 

如果沒有 curl,安裝 curl,或者用 postman 也是可以的

 scoop install curl

 

動態回傳結果

增加 example 節點

為了要讓 OpenApi Spec. 更好被開發人員理解,我們會加上 example 節點,所以我修改了以下內容,增加了 example,這也是動態回傳結果的必要條件

paths:
  /pets:
    get:
	  .....	
      responses:
        '200':
          description: A paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
              example: 
                - id: 10
                  name: "doggie"
                  tag: "dog"
...     

Example 用法請參考

Adding Examples (swagger.io)

 

使用 prism mock 建立動態 Mock Server

prism mock doc/2/index.yaml

執行結果,如下圖:

 

這時候的回傳值都會一直變

curl 127.0.0.1:4010/pets

執行結果,如下圖:



除了 prism mock,也可使用 Query String,通過 __dynamic=key,強制回傳動態結果,範例如下:

prism mock doc/2/index.yaml
curl 127.0.0.1:4010/pets?__dynamic=true

 

指定回傳值

在 /pet/{pedId} 端點新增 examples 節點,裡面有兩組 example,分別是 1 和  12,這個代表的是 example key

paths:
  /pets/{petId}:
    get:
      ....
      responses:
        '200':
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pet"
              examples: 
                1:
                  value: 
                    id: 1
                    name: "doggie"
                    tag: "dog"
                12:
                  value:
                    id: 12
                    name: "dora"
                    tag: "cat"

 

通過 __example=key,來指定回傳內容,範例如下:

curl 127.0.0.1:4010/pets/12?__example=12
curl 127.0.0.1:4010/pets/12?__example=1

執行結果,如下圖:

 

有關 example 的建議寫法會像是 shopify 用一個場景來當 key

Product (shopify.dev)

 

指定錯誤碼(HttpStatus)

在 responses 新增 404 的失敗回傳

/pets/{petId}:
  get:
    ...
    responses:
	  ...
      '404':
        description: Pet not found
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Error"
            example:
              message: "Pet not found"
              status: 404
              code: 404

 

通過 __code=http status,來指定回傳失敗內容,範例如下:

curl 127.0.0.1:4010/pets/12?__code=404

 

參數檢查

在 pattern 節點使用 regex 編寫驗證規則,當條件不符合則會噴錯

/pets/validate:
  get:
    summary: Your GET endpoint
    tags: []
    parameters:
      - schema:
          type: string
          pattern: '^[A-Z]{2} [1-9]{4}$'
          minLength: 0
        in: query
        name: id
        required: true
    responses:
      '200':
        description: Expected response to a valid request
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Pet"
            examples:
              1:
                value:
                  id: 1
                  name: "doggie"
                  tag: "dog"
              12:
                value:
                  id: 12
                  name: "dora"
                  tag: "cat

 

執行結果如下:

curl 127.0.0.1:4010/pets/validate?id=111111

 

範例位置

sample.dotblog/WebAPI/Swagger/Mock Server/Prism at master · yaochangyu/sample.dotblog (github.com)

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo