LoginSignup
33
37

More than 5 years have passed since last update.

Swagger でソースコードのアノテーションからRESTなAPIドキュメントを自動生成する

Last updated at Posted at 2016-04-05

swaggerとは

"API Blueprint"、"RAML"と並ぶAPIドキュメントテーションツール。
RESTful APIの記述標準化を目指す"Open API Initiative"や"Amazon API Gateway"などでも採用されている。

  • jsonより書きやすいyaml形式で記述できるwebエディタがある
    Swagger Editor
  • ソースコードに記述したアノテーションからjson出力することができる
    ⇒ PHPではswagger-php
  • swaggerはjson形式(実際にはyamlで書いてjsonで出力)でAPI定義記述するもので、作成したjsonを元にブラウザで参照・実行できるツールがある
    swagger-ui
  • swaggerのjsonからAPIのコードを生成することができる
    swagger-codegen

今回は、swagger-phpを使用してアノテーションからjsonを生成し、swagger-uiから参照するという流れを試してみる。

前提

  • mac OSX 10.13
  • nginx + php-fpm + php5.6(FuelPHP) on docker

swagger-php

PHPソース上のアノテーションからswaggerドキュメントを作成してくれるライブラリ。

インストール

composerでインストールする

    "require-dev": {
        "zircote/swagger-php": "*",
    }

アノテーション記法

包括的なドキュメントがないような。。。

(追記)
アノテーション記法について書きました
Swagger-PHPでSwagger2.0に対応したアノテーションサンプル

JSON出力

composerで入れたswaggerを実行する

$ fuel/vendor/bin/swagger fuel/app/classes/controller

カレントディレクトリにswagger.jsonが出力される。
-oオプションで出力先を変更可能。

swagger-ui

インストール(docker)

$ git clone https://github.com/swagger-api/swagger-ui.git
$ cd swagger-ui
$ git checkout --force refs/tags/v2.1.4

dockerでビルドできるらしいので試してみたが、npm installの依存性warningのせい?でエラーになってしまった。
しょうがないのでローカルにインストールした。
一応dockerで試した手順も記載しておく(docker-toolboxを使用)

$ docker-machine create --driver=virtualbox swagger
$ docker-machine env swagger
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.101:2376"
export DOCKER_CERT_PATH="/Users/hoge/.docker/machine/machines/swagger"
export DOCKER_MACHINE_NAME="swagger"
# Run this command to configure your shell:
# eval $(docker-machine env swagger)
$ eval $(docker-machine env swagger)
$ docker build -t swagger-ui-builder .

npm installでワーニングが出てしまったので、警告を無視するようにdockerfileを編集してみる。
※macローカルで、npm installでワーニングが出たが、swagger-uiが動作することは確認済み.

swagger-ui/Dockerfile
RUN     npm install
  ↓
RUN     npm install | true

再度 docker build 実行

$ docker build -t swagger-ui-builder .
npm http 200 https://registry.npmjs.org/express
npm http GET https://registry.npmjs.org/express/-/express-4.13.4.tgz
npm http 200 https://registry.npmjs.org/express/-/express-4.13.4.tgz
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /build/npm-debug.log
npm ERR! not ok code 0
 ---> 43f85ad5f9da

Removing intermediate container c3ff9fac51d6
Step 9 : ADD . /build
 ---> c475377473f7
Removing intermediate container e91f262ad758
Step 10 : CMD ./node_modules/gulp/bin/gulp.js serve
 ---> Running in 9ed882094940
 ---> dd2230ad6a05
Removing intermediate container 9ed882094940
Successfully built dd2230ad6a05

npm installではエラーが出力されているが通った。最後の起動は成功しているっぽい。
ただし、次のコンテナ起動がコケてダメだった。。。

$ docker run -p 127.0.0.1:8080:8080 swagger-ui-builder
/bin/sh: 1: ./node_modules/gulp/bin/gulp.js: not found

よく分からないのでローカルにインストールした。

(追記)
docker-composeでコンテナ化しました。
swagger-ui をdockerで使う

インストール(macローカル)

$ npm install
npm WARN bl@0.7.0 requires a peer of stream-browserify@* but none was installed.
$ npm run build

insatllで1件警告が出たけど、とりあえずbuild通った。

サーバ起動

$ npm run serve

ブラウザで http://localhost:8080 にアクセス。

ドキュメント参照

画面上部のテキストボックス(デフォルトではhttp://petstore.swagger.io/v2/swagger.jsonと表示されている)に、対象のjsonへのURLを入力して "Explore"をクリックすればswaggerで記載した内容が表示される。

つまり、読み込む対象のjsonはhttp経由で指定する必要がある。。
ローカルファイルを直接見れないっぽい。。。

なので、先ほど生成したswagger.jsonをドキュメントルートにおいて、http://192.168.99.100:81/swagger.jsonという感じで取得しようとしたが、下記のエラーが発生。

Can't read from server. It may not have the appropriate access-control-origin settings.

今回はAPIをVM上に作成していたためCORSエラーが発生してしまった。。。

これについては、とりあえずnginxに下記の設定を行って回避した。
(後に実際APIを叩く際にもCORS対応が必要なのでphp用のロケーションにも設定しておく)

/etc/nginx/conf.d/default.conf
    location / {
        ...
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS";
        add_header Access-Control-Allow-Headers "Content-Type, Origin, Authorization, Accept";
        add_header Access-Control-Allow-Credentials true;
        ...
    }
    ...
    location ~ \.php$ {
        ...
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS";
        add_header Access-Control-Allow-Headers "Content-Type, Origin, Authorization, Accept";
        add_header Access-Control-Allow-Credentials true;
        ...
    }

これで、とりあえずjsonの内容がブラウザに表示された。

swagger-uiからAPIの実行

各エンドポイントにあるTry it out!ボタンで、実際にAPIを実行することができる。

ただし、メソッドがGET以外の場合、一度OPTIONSメソッドで疎通確認した後に本来のメソッドで実行するというよく分からない挙動をする。。。
初回のOPTIONSメソッドによるアクセスについては200系の正常レスポンスを返してあげないと正しく動かないので、OPTIONSメソッドでアクセスがきたらOKを返すようにする必要がある。

とりあえずnginxの設定で200を返すようにしてみたら、OPTIONSメソッドのアクセスだけで終わってしまった。。

/etc/nginx/conf.d/default.conf
if ($request_method = OPTIONS) {  
    return 200;
}

なので、API側でOPTIONSメソッドだったら処理終了させるようにしたら、その後のPOSTも動いた。
nginxとAPIを別サーバにしているせいかもしれないが、よく分からない。。。

bootprint-swagger

swagger-uiだと、jsonからhtmlを作成しているのでnode上でないと参照できない。。
静的なhtmlが欲しい場合は、変換ツールを使用する。

bootprint-swagger

インストール

$ npm install -g bootprint
$ npm install -g bootprint-swagger

実行

$ mkdir swagger-html
$ bootprint swagger http://192.168.99.100:81/swagger.json swagger-html
Loading bootprint-swagger 0.13.1
Loading bootprint-json-schema 0.8.6
Loading bootprint-base 0.7.2
[ 'swagger-html/index.html',
  'swagger-html/main.css',
  'swagger-html/main.css.map' ]

出力を一つのファイルにまとめたい場合は、別途html-inlineを使う。

$ npm -g install html-inline
$ html-inline swagger-html/index.html

その他

swagger-to-ramlとかもあるので、RAMLにしてからraml2htmlした方が見やすいHTMLになる気はする。。

33
37
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
33
37