PHP環境にSwagger導入

  • 11
    Like
  • 0
    Comment
More than 1 year has passed since last update.

Swaggerとは

Swaggerは言語に依存しないREST APIのインターフェース仕様とそのツール群を指す。
Swaggerの仕様に沿ってAPIを定義することで、人間が理解可能で、コンピューターにも解析可能なAPI仕様書となる。

引用:http://d.hatena.ne.jp/takeR/20151207/1449469957

らしいです。


ともあれ導入

環境

  • CentOS 6.5 x86_64
  • PHP環境(PHP5.5、Nginx1.8)
  • CodeIgniter3.0.6

composerインストール

$ curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading 1.0.0...

Composer successfully installed to: /var/www/api/fuel/composer.phar
Use it: php composer.phar

「php composer.phar 使って」がめんどいので...

pathが通っている場所へ移動&動作確認

$ mv composer.phar /usr/local/bin/composer

$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/

これでcomposerだけでいけるようにしときます。

ComposerによるSwagger追加

codeigniterは最初からcomposer.jsonがあるっぽいのでそこのrequire-devにswagger追記。

/var/www/api/composer.json
"require-dev": {
    ...,
    "zircote/swagger-php": "*"
}

composer.jsonがある場所でcomposer実行。
今回は/var/www/api/

$ composer install

Swaggerの準備はこれでOK。

ついでに定義をブラウザで確認するためのSwagger-UIのインストール

任意の場所にgitからcloneします(後でswagger-ui/distをDocumentRootにする必要あり)。
今回は/var/www/swaggerディレクトリ作成してその中でcloneしました。

$ git clone https://github.com/swagger-api/swagger-ui.git

/var/www/swagger/swagger-ui/dist をDocumentRootにして、一旦確認。

スクリーンショット 2016-04-18 18.31.08.png

見た目はこんなん。

で、読み込むjsonの作成に移っていきます。

定義の書き出しとswagger.jsonの作成
基本的にFWの各コントローラーのアノテーションにAPIの定義を書いていく形になると思います。

書き方については下記サイト様を
gong023の日記
kaz29

最初にAPIのタイトルだったりバージョンなんかを載せるswagger.phpをコントローラーディレクトリに作成します。
わざわざ作成しなくてもコアコントローラーがコントローラーディレクトリにあるようだったらそこのアノテーションに書いていいと思います。

例として簡単に書くとこんな感じ。

application/controller/swagger.php
<?php
/**
 * @SWG\Swagger(
 *   @SWG\Info(
 *     title="Hoge API Document",
 *     version="1.0.0"
 *   )
 * )
 */

次に各コントローラーのエンドポイントごとに定義を書きます。

application/controller/Counting.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Counting extends CI_Controller {

    /**
     * @SWG\Post(
     *     path="/counting",
     *     description="リクエストされた数を返す",
     *     produces={"application/json"},
     *     tags={"hoge"},
     *     @SWG\Parameter(
     *         name="number",
     *         description="数字",
     *         in="path",
     *         required=true,
     *         type="integer"
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Success"
     *     ),
     *     @SWG\Response(
     *         response=404,
     *         description="Parameter error"
     *     ),
     *     @SWG\Response(
     *         response=403,
     *         description="Auth error",
     *     ),
     * )
     * @SWG\Post(
     *     path="/counting/plus",
     *     description="1足す、またはリクエストされたplusを足す",
     *     produces={"application/json"},
     *     tags={"hoge"},
     *     @SWG\Parameter(
     *         name="number",
     *         description="数字",
     *         in="path",
     *         required=true,
     *         type="integer"
     *     ),
     *     @SWG\Parameter(
     *         name="plus",
     *         description="足す数",
     *         in="path",
     *         required=false,
     *         type="integer"
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Success"
     *     ),
     *     @SWG\Response(
     *         response=404,
     *         description="Parameter error"
     *     ),
     *     @SWG\Response(
     *         response=403,
     *         description="Auth error",
     *     ),
     * )
     * @SWG\Post(
     *     path="/counting/remainder",
     *     description="余りを出す",
     *     produces={"application/json"},
     *     tags={"hoge"},
     *     @SWG\Parameter(
     *         name="number",
     *         description="割られる数",
     *         in="path",
     *         required=true,
     *         type="integer"
     *     ),
     *     @SWG\Parameter(
     *         name="division",
     *         description="割る数",
     *         in="path",
     *         required=true,
     *         type="integer"
     *     ),
     *     @SWG\Response(
     *         response=200,
     *         description="Success"
     *     ),
     *     @SWG\Response(
     *         response=404,
     *         description="Parameter error"
     *     ),
     *     @SWG\Response(
     *         response=403,
     *         description="Auth error",
     *     ),
     * )
     */

    public function index() {
        set_status_header($code = 200, $text = 'Success');
        $this->output
        ->set_content_type('application/json')
        ->set_output(json_encode(array('result' => (int) $this->input->post('number'))));
    }

    public function plus() {
        $plus = (int) $this->input->post('plus');
        set_status_header($code = 200, $text = 'Success');
        if (!$plus) {
            $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode(array('result' => (int) $this->input->post('number') + 1)));
            return;
        }
        $this->output
        ->set_content_type('application/json')
        ->set_output(json_encode(array('result' => (int) $this->input->post('number') + $plus)));
    }

    public function remainder() {
        set_status_header($code = 200, $text = 'Success');
        $this->output
        ->set_content_type('application/json')
        ->set_output(json_encode(array('result' => (int) $this->input->post('number') % (int) $this->input->post('division'))));
    }
}

今回はPOSTメソッドのみの記載になります。すいません。。

次にようやくswaggerでソースのアノテーションを読み込ませて、jsonの作成です。

といってもComposerのSwaggerでコントローラーのディレクトリ指定して叩いて終わりです。
$ composerでインストールされたswaggerのディレクトリ/swagger APIコントローラーのディレクトリ

で、今回の例でフルパスで叩くとこんな感じ

$ /var/www/api/vendor/bin/swagger /var/www/api/application/controllers/ -o /var/www/swagger/swagger-ui/dist/

Swagger-PHP 2.0.6
-----------------
   post /counting
   post /counting/plus
   post /counting/remainder
-----------------------
3 operations documented
-----------------------
Written to /var/www/swagger/swagger-ui/dist/swagger.json

-oオプションで指定のディレクトリにjsonが作成できるので、swagger-uiのDocumentRoot直下に置きました。

次に、swagger-ui/dist/index.htmlをいじります。

swagger-ui/dist/index.html
- url = "http://petstore.swagger.io/v2/swagger.json";
+ url = "swagger.json"; // /var/www/swagger/swagger-ui/dist/swagger.json

先ほどswaggerコマンドで作成したswagger.jsonの場所にしてます。
ちなみにこのswagger.jsonを置く場所ですが、DocumentRootが通ってないと読み込めないみたいです。

そしてswagger-uiのアドレスにアクセスすると
スクリーンショット 2016-04-20 11.12.01.png

こんな感じに。。。
Try it out!のボタンで実際にリクエストしたりできるらしいのですが、多分記法が間違っていてうまくいきませんでした。。。

記法に関しては、その他参照してください。

以上です。