PHP環境にSwagger導入

### [Swagger](http://swagger.io/)とは

>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

<b>[composer](http://qiita.com/atwata/items/d6f1cf95ce96ebe58010)インストール</b>

```
$ 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 使って」がめんどいので...

<b>pathが通っている場所へ移動＆動作確認</b>

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

$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
```
これで```composer```だけでいけるようにしときます。

<b>ComposerによるSwagger追加</b>

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

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

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

```
$ composer install
```

Swaggerの準備はこれでOK。

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

任意の場所に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](https://qiita-image-store.s3.amazonaws.com/0/111464/101681b4-8093-c9c7-66a5-a09fe026b7f9.png)

見た目はこんなん。


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

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

書き方については下記サイト様を
[gong023の日記](http://gong023.hatenablog.com/entry/2014/05/15/152021)
[kaz29](http://kaz29.hatenablog.com/entry/2016/02/18/113238)

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

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

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

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

```php: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`をいじります。

```js: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](https://qiita-image-store.s3.amazonaws.com/0/111464/635a7b6f-9f6d-e23d-fc00-f34a3140684b.png)

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

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

以上です。