[swagger-php] AWS API Gateway定義サンプル

SwaggerのSpecファイルを作成し、API Gatewayにインポートすることで…

* API Gateway設定のバージョン管理
* コード - APIドキュメント - API Gateway設定 の同期

が可能になったわけですが、対応から1年近くたった今でもswagger-phpアノテーションの十分なサンプルがありません。
そこで、今回行った試行錯誤の結果を共有したいと思います。私自身はSwaggerもAPI Gatewayも初心者に近いので、コメントでアドバイス等いただけると幸いです。
あと、最近使ったという理由でCognito User Poolsの定義も含めてみました。

swagger-phpのインストール、基本的な使い方については下記記事をご覧ください。

[『LaravelプロジェクトのAPIをswaggerを使ってドキュメント化』](http://qiita.com/wrbss/items/258394193e5ffd1b926a)
[『Swagger-PHPでSwagger2.0に対応したアノテーションサンプル』](http://qiita.com/teratsyk/items/795412717766f4827897)

## アノテーションサンプル(Controller)

共通部分の定義です。
基底コントローラがないプロジェクトでは"swagger.php"等の適当なファイルにアノテーションだけ記述しても構いません。

```
/**
 * @SWG\Swagger(
 *   schemes={"https"},
 *   basePath="/api",
 *   @SWG\Info(
 *     title="Example API", version="1.0"
 *   ),
 *   @SWG\Definition(
 *     definition="Attribute",
 *     @SWG\Property(
 *       property="Name",
 *       type="string"
 *     ),
 *     @SWG\Property(
 *       property="Value",
 *       type="string"
 *     )
 *   ),
 *   @SWG\Definition(
 *     definition="User",
 *     description="Cognito User Data",
 *     @SWG\Property(
 *       property="Username",
 *       type="string"
 *     ),
 *     @SWG\Property(
 *       property="Attributes",
 *       description="Cognito User Attributes",
 *       type="array",
 *       @SWG\Items(ref="#/definitions/Attribute")
 *     ),
 *     @SWG\Property(
 *       property="UserCreateDate",
 *       type="string",
 *       format="date-time"
 *     ),
 *     @SWG\Property(
 *       property="UserLastModifiedDate",
 *       type="string",
 *       format="date-time"
 *     ),
 *     @SWG\Property(
 *       property="Enabled",
 *       type="boolean"
 *     ),
 *     @SWG\Property(
 *       property="UserStatus",
 *       type="string",
 *       description="UNCONFIRMED|CONFIRMED|ARCHIVED|COMPROMISED|UNKNOWN"
 *     )
 *   )
 * )
 * @SWG\Parameter(
 *   name="username",
 *   description="Username on Cognito User Pools",
 *   in="path",
 *   required=true,
 *   type="string"
 * )
 */
class Controller
{
    // 省略
}
```

## アノテーションサンプル(UserController)

リソースごとの定義です。
とりあえず、GET/POSTを一つずつ。後は応用でいけるかと思います。

```
class UserController extends Controller {

    /**
     * Display a listing of the resource.
     *
     * @return Response
     * 
     * @SWG\Get(path="/users",
     *   tags={"users"},
     *   description="List confirmed users",
     *   produces={"application/json"},
     *   x={"amazon-apigateway-integration"={
     *     "type"="http",
     *     "httpMethod"="GET",
     *     "uri"="http://ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com/users",
     *     "responses"={
     *       "200"={
     *         "statusCode": "200"
     *       }
     *     }
     *   }},
     *   @SWG\Response(
     *     response=200,
     *     description="successful operation",
     *     @SWG\Schema(
     *       type="array",
     *       @SWG\Items(ref="#/definitions/User")
     *     )
     *   )
     * )
     */
    public function index()
    {
        // 省略
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param Request $request
     * @return Response
     * 
     * @SWG\Post(path="/users",
     *   tags={"users"},
     *   description="Create new user",
     *   produces={"application/json"},
     *   x={"amazon-apigateway-integration"={
     *     "type"="http",
     *     "httpMethod"="POST",
     *     "uri"="http://ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com/users",
     *     "responses"={
     *       "201"={
     *         "statusCode": "201"
     *       }
     *     }
     *   }},
     *   @SWG\Response(
     *     response=201,
     *     description="successful operation"
     *   )
     * )
     */
    public function store(Request $request)
    {
        // 省略
    }
```

## 課題

生成されたSpecファイルをAPI Gatewayにインポートしてそれだけで完結するのが理想ですが、実際にテストしてみるとPOSTが"Execution failed due to configuration error"というエラーになってしまいます。(GETはOK)
おそらくCORSが原因だと考え、AWSマネジメントコンソールから「リソースのアクション > CORSの有効化」をしてみたのですが、OPTIONSメソッドの定義が必要なようでその定義を手動で行ったりしていました。そこら辺の書き方(アノテーション)はまだ試行錯誤中です。
[AWS API Gateway : Execution failed due to configuration error: No match for output mapping and no default output mapping configured](http://stackoverflow.com/questions/34120135/aws-api-gateway-execution-failed-due-to-configuration-error-no-match-for-outp)

## 公式ドキュメント

どのような設定項目があるのかは公式ドキュメントでご確認ください。
[『Swagger に対する API Gateway 拡張』](http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-swagger-extensions.html)

ついでにCORSのほうも貼っておきます。
[『API Gateway のメソッドを通じてリソースの CORS を有効にする』](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html)