Swaggerをつかってマシンリーダブルな環境を整備する
- 全てがJSONになる
- マシンリーダブルなAPI仕様の記述フォーマットが整備されればこんな喜ばしい未来が
- ドキュメントの自動生成
- MockAPIサーバの自動生成
- APIクライアントの自動生成
- マシンリーダブルなAPI仕様の記述フォーマットが整備されればこんな喜ばしい未来が
- セマンティックWeb
- でもそれはいつか来た道
- SOAP, WSDL, UDDI ...
- Quite:GoConの前哨戦として各種API仕様記述フォーマットについて概要を述べておく
- XMLがJSON、YAMLになっただけかも。。
- Open API Initiative をマイクロソフト、グーグル、IBMらが発足
- いつか来た道アゲイン
- Swagger2.0 を採用
- 「その目的にはこのAPIを使うのが最適です」最適なAPIをワトソンの技術で教えてくれる、米IBMが「API Harmony」発表
- SOAP ⇒ HTTP/JSON でいいんじゃね
- WSDL ⇒ Swagger でいいんじゃね
- ということは UDDI が来るかも!? ← いまここ
Swaggerから手元のAPIプロジェクト(HTTPリクエスト・JSONレスポンス)にアクセスしてみる
たとえばこんなAPI
$ curl http://localhost:9092/v1/spiral/db/DRWeb
{"count":3,"data":[{"comment":"abcd...
レスポンスが CORS(Cross-Origin Resource Sharing) 対応していることを確認
$ curl -I http://localhost:9092/v1/spiral/db/DRWeb
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *
Cache-Control: no-cache
Content-Length: 78587
- 上記ではレスポンスヘッダ Access-Control-Allow-Origin: * が付与されている
- 詳しくは各自調べておくこと
まずは手動で http://editor.swagger.io/ にてAPI定義する
swagger: "2.0"
info:
version: "1.0.0"
title: "ConnectSpiral"
host: "localhost:9092"
basePath: "/v1/spiral"
paths:
/db/{dbName}:
get:
operationId: "select"
parameters:
-
name: "dbName"
in: "path"
required: true
type: "string"
responses:
200:
description: "successful operation"
schema:
type: "array"
items:
type: "string"
サンプル定義 を参考にすると良い
http://editor.swagger.io/ からパラメータセットしてリクエスト送信し、レスポンス取得できることを確認。
- APIプロジェクトが起動しているにも関わらずエラー
ERROR Server not found or an error occurred
となった場合には CORS 設定を確認する。
PlayFramework1でのAPI実装から、SwaggerAPI定義を自動生成する
conf/dependencies.yml にて play-swagger モジュールを導入
require:
- play
- asufana -> swagger 0.0.2
repositories:
- asufana-play-github:
type: http
artifact: "https://github.com/[organization]/play-[module]/raw/master/release/[module]-[revision].zip"
contains:
- asufana -> *
conf/route
* /swagger module:swagger
conf/swagger.yml
swagger: "2.0"
info:
version: "1.0.0"
title: ConnectSpiral
host: "localhost:9092"
basePath: "/v1/spiral"
schemes:
- http
$ curl http://localhost:9092/swagger/swagger.json
{
"swagger" : "2.0",
"info" : {
"version" : "1.0.0",
"title" : "ConnectSpiral"
},
"host" : "localhost:9092",
"basePath" : "/v1/spiral"
}
Swaggerアノテーション仕様 を参考に、API実装にアノテーションを付与
- @Api, @ApiOperation, @ApiParam が Swaggerアノテーション
- @Get, @Path, @PathParam は JAX-RS アノテーション
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import domain.models.api.select.SelectApi;
import domain.models.api.select.SelectDto;
import play.mvc.Before;
import play.mvc.Controller;
@Api(value = "/", description = "Spiral CRUD oprations")
public class Application extends Controller {
@GET
@Path("/db/{dbName}")
@ApiOperation(value = "Fetch db records", response = SelectDto.class)
public static void select(@ApiParam(required = true) @PathParam("dbName") final String dbName) {
final SelectDto dto = SelectApi.get(dbName);
renderJSON(dto);
}
@Before
static void checkAuthentification() {
response.setHeader("Access-Control-Allow-Origin", "*");
}
}
import java.util.List;
import java.util.Map;
import com.wordnik.swagger.annotations.ApiModel;
import com.wordnik.swagger.annotations.ApiModelProperty;
import lombok.Value;
import lombok.experimental.Accessors;
@ApiModel
@Value
@Accessors(fluent = true)
public class SelectDto {
@ApiModelProperty
private String url;
@ApiModelProperty
private Integer count;
@ApiModelProperty
private List<Map<String, String>> data;
}
アノテーション指示によりSwaggerAPI定義が生成されることを確認
$ curl http://localhost:9092/swagger/swagger.json
{
"swagger" : "2.0",
"info" : {
"version" : "1.0.0",
"title" : "ConnectSpiral"
},
"host" : "localhost:9092",
"basePath" : "/v1/spiral",
"tags" : [ {
"name" : "",
"description" : "Spiral CRUD oprations"
} ],
"paths" : {
"/db/{dbName}" : {
"get" : {
"tags" : [ "" ],
"summary" : "Fetch db records",
"description" : "",
"operationId" : "select",
"parameters" : [ {
"name" : "dbName",
"in" : "path",
"description" : "",
"required" : true,
"type" : "string"
} ],
"responses" : {
"200" : {
"description" : "successful operation",
"schema" : {
"type" : "array",
"items" : {
"$ref" : "#/definitions/SelectDto"
}
}
}
}
}
}
},
"definitions" : {
"SelectDto" : { }
}
}
- schemes設定が反映されないので手当必要
- 後述するAPIクライアント自動生成時にschemes設定しないとhttpsアクセスとなるため
上記 JSON を yaml に変換し、http://editor.swagger.io/ にて利用できることを確認する
- Docker for Mac をインストール
- swagger-ui 起動する
$ docker run -d -p 8080:80 schickling/swagger-ui
- http://localhost:8080/ にアクセスして swagger-ui にアクセスできることを確認する
swagger-ui の停止
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9331c93432d2 schickling/swagger-ui "sh run.sh" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp admiring_kowalevski
$ docker stop 9331c93432d2
http://localhost:8080/ にて http://localhost:9092/swagger/swagger.json を設定し、API定義が読み込まれること、API呼び出しができることを確認する
http://editor.swagger.io/ から Generate Client
するだけ。APIクライアントの実装プロジェクトを生成してくれる。