LoginSignup
1
2

More than 3 years have passed since last update.

Hello, OpenAPI - PrismでPetstoreのモックサーバを立てる

Last updated at Posted at 2020-08-16

はじめに

OpenAPI 界隈では Hello World の代わりにペットストアを開業することになっているらしいのでやってみた(みんな知ってる petsoter.yaml から Prism でモックサーバを立ち上げて遊びます)

Prism

  • Prism は、OpenAPI仕様の yamljson を読み込んでモックサーバを立ててくれます
  • モックサーバに向かってHTTPリクエスト投げると、それなりにいい感じの応答をしてくれます
  • モックなんでロジックはありませんが、HTTPヘッダ・認証・データのフォーマットチェックなどそれなりにやってくれます

petsoter.yaml を読み込みつつ Prism を立ち上げる

  • おもむろに docker でいきます
$ docker run --rm -it -p 4010:4010 stoplight/prism:3 mock -d -h 0.0.0.0 https://raw.githubusercontent.com/openapitools/openapi-generator/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml

[1:54:08 AM] › [CLI] …  awaiting  Starting Prism…
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/pet
[1:54:09 AM] › [CLI] ℹ  info      PUT        http://0.0.0.0:4010/pet
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/pet/findByStatus
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/pet/findByTags
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/pet/303
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/pet/174
[1:54:09 AM] › [CLI] ℹ  info      DELETE     http://0.0.0.0:4010/pet/790
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/pet/574/uploadImage
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/store/inventory
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/store/order
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/store/order/2
[1:54:09 AM] › [CLI] ℹ  info      DELETE     http://0.0.0.0:4010/store/order/et
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/user
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/user/createWithArray
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/user/createWithList
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/user/login?username=et&password=libero
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/user/logout
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/user/voluptatibus
[1:54:09 AM] › [CLI] ℹ  info      PUT        http://0.0.0.0:4010/user/reiciendis
[1:54:09 AM] › [CLI] ℹ  info      DELETE     http://0.0.0.0:4010/user/quae
[1:54:09 AM] › [CLI] ▶  start     Prism is listening on http://0.0.0.0:4010
  • -d つけておくと、ランダムにそれっぽいレスポンスデータを返してくれる

curl 投げつける

GET する

$ curl -s -H 'api_key: special-key' -H "Accept: Application/json" localhost:4010/pet/1 | json_pp
{
   "category" : {
      "id" : 7155740,
      "name" : "mollit in"
   },
   "id" : 87883213,
   "name" : "eiusmod dolor in sed id",
   "photoUrls" : [
      "est Ut cupidatat incididunt tempor",
      "ullamco ut ea ex veniam",
      "aliquip mollit proident sit",
      "minim ullamco id et",
      "ut labore non magna"
   ],
   "status" : "sold",
   "tags" : [
      {
         "id" : 35811162,
         "name" : "et cupidatat"
      },
      {
         "id" : -26616885,
         "name" : "sint ut non"
      }
   ]
}
  • -H 'api_key: special-key' しないと認証できない1
APIキーがないと
$ curl -s -H "Accept: Application/json" localhost:4010/pet/1 | json_pp
{
   "detail" : "Your request does not fullfil the security requirements and no HTTP unauthorized response was found in the spec, so Prism is generating this error for you.",
   "status" : 401,
   "title" : "Invalid security scheme used",
   "type" : "https://stoplight.io/prism/errors#UNAUTHORIZED"
}
  • -H "Accept: Application/json" としないと xml でレスポンスが返ってくる
Acceptを指定しないと
$ curl -X GET -H 'api_key: special-key' -H 'Content-Type: application/json' localhost:4010/pet/414
<xml><id>0</id><category><id>0</id><name>string</name></category><name>doggie</name><photoUrls>string</photoUrls><tags><id>0</id><name>string</name></tags><status>available</status></xml>d030

POST する

  • POST はデフォルトで認証周りが OAuth になって面倒。今回のポイントはそこじゃないので、認証をスキップするように petstore.yaml を書き換えます。大胆にコメントアウト
  • ちなみにここ securityDefinitions: でリクエストのヘッダに渡すべきAPIキーの設定もされている
petstore.yaml
securityDefinitions:
  petstore_auth:
#    type: oauth2
#    authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
#    flow: implicit
#    scopes:
#      'write:pets': modify pets in your account
#      'read:pets': read your pets
  api_key:
    type: apiKey
    name: api_key
    in: header
  • さらに、200 OK の処理が定義されていないようなので(結構いいかげんやな..)、付け足しておきます
  • /pet:responses:'200': を設定してみます
petstore.yaml
      responses:
        '200':
          description: A pet added
          schema:
            type: array
            items:
              $ref: '#/definitions/Pet'
        '405':
          description: Invalid input
  • petstore.yaml を読み込みます2
$ docker run --rm -it -p 4010:4010 -v $PWD:/tmp stoplight/prism:3 mock -d -h 0.0.0.0 /tmp/petstore.yaml

[1:54:08 AM] › [CLI] …  awaiting  Starting Prism…
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/pet
[1:54:09 AM] › [CLI] ℹ  info      PUT        http://0.0.0.0:4010/pet
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/pet/findByStatus
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/pet/findByTags
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/pet/303
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/pet/174
[1:54:09 AM] › [CLI] ℹ  info      DELETE     http://0.0.0.0:4010/pet/790
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/pet/574/uploadImage
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/store/inventory
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/store/order
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/store/order/2
[1:54:09 AM] › [CLI] ℹ  info      DELETE     http://0.0.0.0:4010/store/order/et
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/user
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/user/createWithArray
[1:54:09 AM] › [CLI] ℹ  info      POST       http://0.0.0.0:4010/user/createWithList
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/user/login?username=et&password=libero
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/user/logout
[1:54:09 AM] › [CLI] ℹ  info      GET        http://0.0.0.0:4010/user/voluptatibus
[1:54:09 AM] › [CLI] ℹ  info      PUT        http://0.0.0.0:4010/user/reiciendis
[1:54:09 AM] › [CLI] ℹ  info      DELETE     http://0.0.0.0:4010/user/quae
[1:54:09 AM] › [CLI] ▶  start     Prism is listening on http://0.0.0.0:4010
pet.json
 {
    "category" : {
       "id" : 0,
       "name" : "string"
    },
    "id" : 0,
    "name" : "doggie",
    "photoUrls" : [
       "string"
    ],
    "status" : "available",
    "tags" : [
       {
          "id" : 0,
          "name" : "string"
       }
    ]
 }
  • 投げつけます
$ curl -X POST -H "accept: application/json" -s "localhost:4010/pet" -H  "Content-Type: application/json" -d @pet.json | json_pp
[
   {
      "category" : {
         "id" : 0,
         "name" : "string"
      },
      "id" : 0,
      "name" : "doggie",
      "photoUrls" : [
         "string"
      ],
      "status" : "available",
      "tags" : [
         {
            "id" : 0,
            "name" : "string"
         }
      ]
   }
]
  • -H "Content-Type: application/json" がないとエラーになる
Content-Typeがないと
$ curl -X POST -H "accept: application/json" -s "localhost:4010/pet" -d @pet.json | json_pp
{
   "detail" : "Your request is not valid and no HTTP validation response was found in the spec, so Prism is generating this error for you.",
   "status" : 422,
   "title" : "Invalid request body payload",
   "type" : "https://stoplight.io/prism/errors#UNPROCESSABLE_ENTITY",
   "validation" : [
      {
         "code" : "required",
         "location" : [
            "body"
         ],
         "message" : "should have required property 'name'",
         "severity" : "Error"
      },
      {
         "code" : "required",
         "location" : [
            "body"
         ],
         "message" : "should have required property 'photoUrls'",
         "severity" : "Error"
      }
   ]
}
  • サーバ側もこんな 200 OK な感じ。よしとしましょう
[1:30:59 AM] › [HTTP SERVER] post /pet ℹ  info      Request received
[1:30:59 AM] › [NEGOTIATOR] ℹ  info      Request contains an accept header: application/json
[1:30:59 AM] › [VALIDATOR] ✔  success   The request passed the validation rules. Looking for the best response
[1:30:59 AM] › [NEGOTIATOR] ✔  success   Found a compatible content for application/json
[1:30:59 AM] › [NEGOTIATOR] ✔  success   Responding with the requested status code 200
  • さっきのところで、認証をコメントアウトしないとこんな感じになるでしょう
認証をコメントアウトしないと
$ curl -X POST -d @pet.json -s -H 'api_key: special-key' -H "Accept: Application/json" localhost:4010/pet/1 | json_pp
{
   "detail" : "Your request does not fullfil the security requirements and no HTTP unauthorized response was found in the spec, so Prism is generating this error for you.",
   "headers" : {
      "WWW-Authenticate" : "OAuth2"
   },
   "status" : 401,
   "title" : "Invalid security scheme used",
   "type" : "https://stoplight.io/prism/errors#UNAUTHORIZED"
}
  • また '200': を設定しないとこんなかんじになるでしょう。特に問題はないですが、成功した雰囲気がでません
200を設定しないと
$ curl -X POST -H "accept: application/json" -s "localhost:4010/pet" "accept: application/json" -H  "Content-Type: application/json" -d @pet.json | json_pp
{
   "detail" : "",
   "status" : 500,
   "title" : "No response in the range 200-299 defined",
   "type" : "https://stoplight.io/prism/errors#NO_SUCCESS_RESPONSE_DEFINED"
}

よし、だいたいわかった。先に進めそうです。

参考にしたサイト


  1. 実はこのキー文字列はなんでもよい 

  2. Prismは petstore.yaml を書き換えるとオートリロードしてくれるので通常はコンテナの再起動は不要 

1
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
1
2