LaravelにSwaggerでAPIドキュメントを一つ書く（1/2)

# はじめに
長いので全2回に分けます。
第一回は、swagger-uiの導入までを書きます。
第二回では、実際にAPIを作ります。

## 0.環境
Vagrant上です。
OS

```
[（≧∀≦）:~]$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
nginx
[（≧∀≦）:~]$ nginx -v
nginx version: nginx/1.10.1
php
[（≧∀≦）:~]$ php -v
PHP 7.0.0 (cli) (built: Apr 22 2016 08:35:27) ( NTS )
laravel
[（≧∀≦）:~/var/www/swagger]$ php artisan --version
Laravel Framework version 5.2.36
[（≧∀≦）:~/var/www/swagger]$ ./vendor/bin/swagger -v
2.0.7
```

## 1.composerでlaravelをインストール

```
composer global require "laravel/installer=~1.1"
```

## 2.~/.bash_profileにcomposerのパスを追加

```
[（≧∀≦）:~]$ vim .bash_profile
```

これを追記

```
PATH=$PATH:$HOME/.composer/vendor/bin
export PATH
```

変更を反映

```
[（≧∀≦）:~]$ source ~/.bash_profile
```

## 3.laravelのプロジェクトを作る
プロジェクトを作りたいところで実行する。
今回は~/var/www/swaggerで作っていきます。

```
[（≧∀≦）:~/var/www]$ laravel new swagger
ｺﾞﾆｮｺﾞﾆｮ.....
.....ｺﾞﾆｮｺﾞﾆｮ
Application ready! Build something amazing. <-これでたらOK
[（≧∀≦）:~/var/www]$ ls -al
drwxrwxrwx 1 vagrant vagrant 238  2月 22 02:02 .
drwxr-xr-x 3 root    root     21  2月 22 02:02 ..
drwxrwxrwx 1 vagrant vagrant 782  2月 22 22:22 swagger
[（≧∀≦）:~/var/www]$ chmod -R 777 swagger/storage
```

## 4.nginxの設定
nginxの設定をします。
nginxってNginXだったり、NGinxだったりするけどどれが人気なんだろう

```
[（≧∀≦）:~/var/www]$ sudo vim /etc/nginx/conf.d/swagger.conf
```

下をコピペ。

```/etc/nginx/conf.d/swagger.conf
server {
  listen 80;
  server_name swagger.dev; # hostsでvagrantに向ける
  root /var/www/swagger;   # laravelのプロジェクト置き場
  index index.php index.html;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;

    include fastcgi_params;
  }
}
```

ついでにhostsファイルに

```
192.168.11.11  swagger.dev
```

を追記

## 5.とりあえずアクセスしてみる。
できたら、Laravel 5のホームが出る
できなかったら、vagrantFileでvagrantのアクセス権限を追加
アプリケーションのディレクトリをsynced_folderで設定しているところがあると思うので、
mount_optionsを追加する。
例:

```
config.vm.synced_folder "app", "/var/www//", create: false, mount_options: ['dmode=777','fmode=777']
```

それでも出ない時はconfを見直す。
それでもだめなら、頑張る。

## 6.swagger-phpの追加
swagger-phpをcomposerを使って導入します。

```
[（≧∀≦）:~/var/www/swagger]$ composer require zircote/swagger-php
ｺﾞﾆｮｺﾞﾆｮ.....
.....ｺﾞﾆｮｺﾞﾆｮ
Writing lock file
Generating autoload files
> Illuminate\Foundation\ComposerScripts::postUpdate
> php artisan optimize
Generating optimized class loader<-これでたらOK
```

次に、artisanからSwaggerController.phpを作成します。

```
[（≧∀≦）:~/var/www/swagger]$ php artisan make:controller SwaggerController
Controller created successfully.<-これでたらOK
```

laravelのコントローラは下記に出力されます。


Swaggerのルートドキュメントオブジェクトを返します。

```~/var/www/swagger/app/Http/Controllers/SwaggerController.php
<?php
namespace App\Http\Controllers
class SwaggerController extends Controller
{
    public function doc()
    {
        $swagger = \Swagger\scan(realpath(__DIR__.'/../../'));
        return response()->json($swagger);
    }
}
```

このコントローラへのルーティングを行います。

```~/var/www/swagger/app/Http/routes.php
// これを追加
Route::get('/swagger/doc', 'SwaggerController@doc');
```

ここから、Swaggerのアノテーションを書いていきます。
下記URLにドキュメントがあるので、参考にしてください。

```
http://swagger.io/specification/
```


注意するのは以下の2点

- 項目毎にネストのルールがあり、決まったネスト外では書けない。
- 項目内に記載するSchemaで必須のものがある。

api.phpに、下記のようにアノテーションを記載します。
また、後で追加するSwaggerJsonを返すようにコントローラに記載します。
api.phpは読み込まれてればいいのですが、レスポンス等のアノテーションもコントローラに書くので
コントローラのディレクトリに置きます。


```~/var/www/swagger/app/Http/Controllers/api.php
<?php
/**
 * @SWG\Swagger(
 *     basePath="/",
 *     host="swagger.dev",
 *     schemes={"http"},
 *     @SWG\Info(
 *         version="0.0.1",
 *         title="Swagger API",
 *         @SWG\Contact(name="ContactName", url="http://ContactURL"),
 *         @SWG\License(name="LicenseName, url="http://LicenseURL")
 *     )
 * )
 */
```

 - @SWG\Swagger
- API仕様のルートドキュメントオブジェクト
 - @SWG\Info
 - Swaggerの基本情報
 - titleとversionが必須


最後にswagger-uiに読ませるJsonを生成します。
swagger.jsonはpublic/swagger/swagger.jsonのように置くことにします。
次にswaggerコマンドでswagger.jsonを生成します。

```
[（≧∀≦）:~/var/www/swagger/laravel]$ mkdir public/swagger
[（≧∀≦）:~/var/www/swagger/laravel]$ ./vendor/bin/swagger ~/var/www/swagger/app/Http/Controllers/ -o ./public/swagger/swagger.json
```

第一引数でアノテーションを書いた場所を指定しておくと早い。
-o で出力先を指定します。
--output (-o)     Path to store the generated documentation.

## 7.swagger-uiの追加
swagger-uiを導入します。

swagger-uiはpublic以下にswagger-uiディレクトリを作成して置くことにします。

```
[（≧∀≦）:~/var/www/swagger]$ cd laravel/public/
[（≧∀≦）:~/var/www/swagger/public]$ mkdir swagger-ui
[（≧∀≦）:~/var/www/swagger/public]$ ll
-rwxrwxrwx 1 vagrant vagrant    0  6月 10 05:18 favicon.ico
-rwxrwxrwx 1 vagrant vagrant 1786  6月 10 05:18 index.php
-rwxrwxrwx 1 vagrant vagrant   24  6月 10 05:18 robots.txt
drwxrwxrwx 1 vagrant vagrant  374  6月 29 03:57 swagger-ui
-rwxrwxrwx 1 vagrant vagrant  914  6月 10 05:18 web.config
```

swagger-uiを拾ってきます。
下記URLのdistの中身がswagger-uiの中身になります。
https://github.com/swagger-api/swagger-ui

distの中身を~/var/www/swagger/public/swagger-uiにコピーします。
index.htmlのjsの中でswagger.jsonのURLを指定します。

```~/var/www/swagger/public/swagger-ui/index.html
  <script type="text/javascript">
    $(function () {
      var url = window.location.search.match(/url=([^&]+)/);
      if (url && url.length > 1) {
        url = decodeURIComponent(url[1]);
      } else {
        //url = "http://petstore.swagger.io/v2/swagger.json";
        url = "http://swagger.dev/swagger/swagger.json";
      }
```

ここまででswagger-uiの準備は終わったので、swagger-uiを開いてみます。
上記までの設定通りであれば、このURLでアクセスできます。
http://swagger.dev/swagger-ui

## 最後に
第一回はここまでです。
第二回も早めに書くぞー