Prismでモックサーバーを構築する
皆さん、こんにちは。技術開発グループのn-ozawanです。
今年も日本人がイグノーベル賞を受賞しましたね。これで18年連続の受賞となりました。
本題です。
フロントエンドを新規開発しているときに、フロンドエンドから呼び出すAPIが開発済みであることは、ほとんどありません。APIをモック動作させることが出来れば、フロントエンドの開発は捗ることでしょう。今回は、OpenAPIで作成したAPI仕様書を元に使ってモックサーバーを構築できる、Prismについてお話しします。
目次
Prism
概要
PrismはStoplightが提供する、OpenAPIで記述されたAPI仕様書を元に動作するモックサーバーです。node.jsの環境があれば、以下のコマンドでインストールすることが出来ます。
npm i -D @stoplight/prism-cli
今回は以下のAPI仕様を元に、Prismの動きを見ていきたいと思います。
openapi: 3.1.0
info:
title: OpenAPI 仕様書 サンプル
version: 0.0.1
description: OpenAPIで記述したAPI仕様書のサンプルです。
paths:
/api/user/{userId}:
get:
operationId: getUserInfo
summary: ユーザー情報取得
description: ユーザー情報を取得する
parameters:
- name: userId
in: path
description: ユーザーID
required: true
schema:
type: integer
responses:
'200':
description: 成功
content:
application/json:
schema:
type: object
properties:
userId:
description: ユーザーID
type: integer
name:
description: ユーザー名
type: string
age:
description: 年齢
type: integer
'400':
description: Bad Request.
'404':
description: Not Found.
Prism Mock を動かしてみる。
Prism Mockを起動してみましょう。以下のコマンドでPrismサーバーを起動します。
npx prism mock ./openapi.yaml
(省略)
[1:23:20 PM] › [CLI] ▶ start Prism is listening on http://127.0.0.1:4010
以下のコマンドで動作を確認してみましょう。
curl -i http://localhost:4010/api/user/1
HTTP/1.1 200 OK
(省略)
{"userId":0,"name":"string","age":0}
200応答がありましたね!
返却値を指定したい
レスポンスがあったのは良いのですが、なんだか内容が味気ないですね。返却値をそれっぽく見せたい場合は、schemaと同じレベルにexamplesを定義することで、返却する内容を変えることが出来ます。
schema:
(省略)
examples:
tarou:
summary: 太郎の情報
value:
userId: 1
name: 太郎
age: 20
curl -i http://localhost:4010/api/user/1
HTTP/1.1 200 OK
(省略)
{"userId":1,"name":"太郎","age":20}
太郎の情報が返ってきましたね!
返却値を動的に変えたい
いちいちexamples
を定義するのが面倒なので、なんでもいいから適当な値を入れたいケースもあるかもしれません。Prismには動的に値を設定してくれる機能があります。-d
を付与してPrismサーバーを起動します。
npx prism mock ./openapi.yaml -d
もう一回リクエストを送信してみましょう。
curl -i http://localhost:4010/api/user/1
HTTP/1.1 200 OK
(省略)
{"age":33300731,"name":"mollit consectetur aliquip dolor","userId":14850756}
値が設定されましたね。ただ、年齢の値がすごいことになっています。この場合、openapi.yaml
の年齢のところに、minimum
とmaximum
を指定することである程度制御することが可能です。
age:
description: 年齢
type: integer
minimum: 0
maximum: 120
curl -i http://localhost:4010/api/user/1
HTTP/1.1 200 OK
(省略)
{"age":74,"name":"Ut","userId":55789416}
ただし、-d
を付与した場合の注意点としては以下があり、実際に開発に使うのは難しそうです。
- 一部の項目だけを動的に変えることは出来ない
→全ての項目が動的に変わってしまう。 examples
の定義は無視される。
→このAPIはexamples
の内容を返却して、別のAPIは動的に変える、などと言ったことが出来ない。- APIを呼び出すたびに返却される値が変わる
→常に同じ値を返して欲しい、ということが出来ない。
呼び出したAPIの内容をチェックしたい
PrismはAPI仕様書と異なるリクエストを受けた場合、エラー応答をしてくれます。
curl -i http://localhost:4010/api/user/hoge
HTTP/1.1 400 Bad Request
上記のURLで{userId}
の個所にhoge
を指定しています。API仕様書ではURLの{userId}
にはtype: integer
を指定しているため、Prismは不正なリクエストであると判断して400エラーを返却します。もし間違ったAPI呼び出しを実装しても、早期に気付くことが出来ます。
なお、Prismは、API仕様に400が記載されているため、400で応答してくれました。もし、API仕様に400が無い場合は422で応答します。
responses:
'200':
(省略)
'400':
description: Bad Request.
レスポンスの内容を出し分けたい
例えば{userId}
に1
を指定した場合は太郎の情報を、{userId}
に2
を指定した場合は次郎の情報を返却したい、などのように、リクエストの内容によってレスポンスを変えたい場合もあります。しかし、残念なことにPrismはそのような動きに対応していません。代わりに以下のようなことは可能です。
まず、examples
に次郎の情報を追加します。
schema:
(省略)
examples:
tarou:
value:
userId: 1
name: 太郎
age: 20
jirou:
value:
userId: 2
name: 次郎
age: 18
HTTPヘッダのPrefer
にexample=jirou
のように指定することで、該当する情報が返却されます。
curl -i http://localhost:4010/api/user/1 -H "Prefer:example=jirou"
HTTP/1.1 200 OK
(省略)
{"userId":2,"name":"次郎","age":18}
APIのモックサーバーは、言ってしまえばAPIが開発されるまでの繋ぎです。あとはテスト用でしょうか。その為にHTTPヘッダにPrefer
を実装をするのは避けたいところです。
画像ファイルなどのバイナリを返却したい
出来ません。残念ながらPrismは画像ファイルなどのバイナリに対応していません。
おわりに
「APIが開発されるまでの繋ぎ」と割り切れば、Prismはそこそこ使えるのではないでしょうか。ただ、個人的にはリクエストの内容によってレスポンスを変えられなかったり、画像ファイルなどのバイナリに対応していないなど、痒いところに手が届かないのが気になります。これらに対応するのであれば、Prismの前にサーバーを置いて別途対応するなどが考えられますが、そうなると手軽さから遠ざかりますね。
ではまた。