Skip to content

Instantly share code, notes, and snippets.

@asufana
Last active June 7, 2020 00:26
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save asufana/bbba543dce153f6f14c7c9b945f51118 to your computer and use it in GitHub Desktop.
Save asufana/bbba543dce153f6f14c7c9b945f51118 to your computer and use it in GitHub Desktop.
Swagger入門

Swagger入門

Swaggerをつかってマシンリーダブルな環境を整備する

0. API仕様記述について

1. Swaggerを使ってみる

Swaggerから手元のAPIプロジェクト(HTTPリクエスト・JSONレスポンス)にアクセスしてみる

1.1. APIプロジェクト用意

たとえばこんな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: * が付与されている
  • 詳しくは各自調べておくこと

1.2. API定義する

まずは手動で 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"

サンプル定義 を参考にすると良い

1.3. API定義からAPIリクエストしてみる

http://editor.swagger.io/ からパラメータセットしてリクエスト送信し、レスポンス取得できることを確認。

  • APIプロジェクトが起動しているにも関わらずエラー ERROR Server not found or an error occurred となった場合には CORS 設定を確認する。

2. API実装からAPI定義を生成する

PlayFramework1でのAPI実装から、SwaggerAPI定義を自動生成する

2.1. Swaggerモジュールを導入

2.1.1. モジュールインストール

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 -> *

2.1.2. API定義表示route定義

conf/route

*   /swagger   module:swagger

2.1.3. API基本定義

conf/swagger.yml

swagger: "2.0"
info:
  version: "1.0.0"
  title: ConnectSpiral
host: "localhost:9092"
basePath: "/v1/spiral"
schemes:
  - http

2.1.4. モジュール動作確認

$ curl http://localhost:9092/swagger/swagger.json
{
  "swagger" : "2.0",
  "info" : {
    "version" : "1.0.0",
    "title" : "ConnectSpiral"
  },
  "host" : "localhost:9092",
  "basePath" : "/v1/spiral"
}

2.2. API実装にSwaggerアノテーションを付与する

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アクセスとなるため

2.3. 定義の正らしさを確認する

上記 JSON を yaml に変換し、http://editor.swagger.io/ にて利用できることを確認する

3. Swagger環境をローカルに整備する

3.1. Swagger-UI のインストール

$ docker run -d -p 8080:80 schickling/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

3.2. API定義の読み込み

http://localhost:8080/ にて http://localhost:9092/swagger/swagger.json を設定し、API定義が読み込まれること、API呼び出しができることを確認する

4. API定義からAPIクライアントを生成する

http://editor.swagger.io/ から Generate Client するだけ。APIクライアントの実装プロジェクトを生成してくれる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment