@r7kamuraさん作のRack::JsonSchemaのspecupを利用して
JSON Schemaを元にダミーレスポンスサーバーを起動します
準備
Rack::JsonSchemaについては@r7kamuraさん本人による下記のエントリをチェック
サンプル
- あらかじめ rack-json_schema gem をインストールしておきます
JSON Schema
schema.json
{
"description": "このスキーマ定義では、Sample API v1 のインターフェースをJSON Hyper Schema draft v4形式で表現しています。",
"links": [
{
"method": "GET",
"title": "{:href=>\"http://localhost:3000\", :rel=>\"self\"}"
}
],
"properties": {
"people": {
"links": [
{
"description": "全ての人物の一覧を取得します。",
"href": "/api/v1/people",
"method": "GET",
"rel": "instances",
"title": "list"
},
{
"description": "人物を取得します。",
"href": "/api/v1/people/:id",
"method": "GET",
"rel": "self",
"title": "get"
},
{
"description": "人物を登録します。",
"href": "/api/v1/people/:id",
"method": "POST",
"rel": "self",
"schema": {
"properties": {
"name": {
"description": "人物の名前",
"example": "tanaka",
"type": "string"
},
"age": {
"description": "人物の年齢",
"example": 34,
"type": "integer"
}
},
"required": [
"name",
"age"
]
},
"title": "create"
},
{
"description": "人物を更新します。",
"href": "/api/v1/people/:id",
"method": "PATCH",
"rel": "self",
"schema": {
"properties": {
"name": {
"description": "人物の名前",
"example": "tanaka",
"type": "string"
},
"age": {
"description": "人物の年齢",
"example": 34,
"type": "integer"
}
},
"required": [
"name",
"age"
]
},
"title": "update"
},
{
"description": "人物を削除します。",
"href": "/api/v1/people/:id",
"method": "DELETE",
"rel": "self",
"title": "delete"
}
],
"properties": {
"id": {
"description": "人物のid",
"example": 1,
"type": "integer"
},
"name": {
"description": "人物の名前",
"example": "tanaka",
"type": "string"
},
"age": {
"description": "人物の年齢",
"example": 34,
"type": "integer"
}
},
"required": [
"id",
"name",
"age"
],
"title": "Person"
}
},
"required": [
"people"
],
"title": "Sample API v1 JSON Schema"
}
動作確認
specup
specupでダミーレスポンスサーバーを起動します
$ specup schema.json
[2015-08-05 04:54:09] INFO WEBrick 1.3.1
[2015-08-05 04:54:09] INFO ruby 2.2.0 (2014-12-25) [x86_64-linux]
[2015-08-05 04:54:09] INFO WEBrick::HTTPServer#start: pid=2041 port=8080
Schema
$ curl -X GET http://localhost:8080/schema
# json schemaが出力される
Docs
$ curl -X GET http://localhost:8080/docs
# HTML形式のSchemaドキュメントが出力される
リスト参照
$ curl -X GET http://localhost:8080/api/v1/people
[
{
"id": 1,
"name": "tanaka",
"age": 34
}
]
1件参照
$ curl -X GET http://localhost:8080/api/v1/people/1
{
"id": 1,
"name": "tanaka",
"age": 34
}
登録
$ curl -X GET http://localhost:8080/api/v1/people/1
{
"id": 1,
"name": "tanaka",
"age": 34
}
更新
$ curl -X PATCH -H "Content-Type: application/json" -d \
'{"name":"hoge_update", "age": 12345}' http://localhost:8080/api/v1/people/1
{
"id": 1,
"name": "tanaka",
"age": 34
}
- わざと不正データを送る: age を文字列にする
$ curl -X PATCH -H "Content-Type: application/json" -d \
'{"name":"hoge_update", "age": "12345"}' http://localhost:8080/api/v1/people/1
{
"id": "invalid_parameter",
"message": "Invalid request.\n#/age: failed schema #/properties/person/links/3/schema/properties/age: \"12345\" is not a integer."
}
- わざと不正データを送る: age なし
$ curl -X PATCH -H "Content-Type: application/json" -d \
'{"name":"hoge_update"}' http://localhost:8080/api/v1/people/1
{
"id": "invalid_parameter",
"message": "Invalid request.\n#: failed schema #/properties/person/links/3/schema: \"age\" wasn't supplied."
}
削除
$ curl -X DELETE http://localhost:8080/api/v1/people/7
{
"id": 1,
"name": "tanaka",
"age": 34
}
不正リンク
linksで定義していないリクエストを送る
$ curl -X GET http://localhost:8080/api/v1/hoge/
{
"id": "link_not_found",
"message": "Could not find the link definition for request path /api/v1/hoge/."
}