この記事は、温かみのある手作業で swagger-php の annotation を書かなければいけない人向けに、コピペで使えるannotationを提供する目的でまとめます。
単なる key value 表現のannotation
出力例
{
"id": "1",
"name": "サンプル太郎",
"email": "example@hoge.com",
"created_at": "2006-04-13T14:12:53+09:00"
}
annotation
/**
* @OA\Get(
* tags={"Common"},
* path="/api/user",
* @OA\Response(
* response="200",
* description="success",
* @OA\JsonContent(ref="#/components/schemas/user_responder")
* ),
* @OA\Response(
* response="204",
* description="there is no authorized user",
* @OA\JsonContent(ref="#/components/schemas/204_no_content")
* )
* )
*/
tags は swagger-ui で見るときに整理されて見えるので便利のためにつけてます。
Response については別のところで定義した schema を参照するようにして、リクエストとレスポンスを別々に定義できるようにしています。
以下は schema の書き方です。
まずはシンプルな方式から。
/**
* @OA\Schema(
* schema="user_responder",
* required={"id", "name", "email", "created_at"},
* @OA\Property(
* property="id",
* type="integer",
* description="ユーザID",
* example="1"
* ),
* @OA\Property(
* property="name",
* type="string",
* description="ユーザの名前",
* example="サンプル太郎"
* ),
* ~その他フィールド略。追加する場合にはカンマを忘れがちなのでお気をつけて~
* )
*/
クラスやフィールドに寄り添った書き方。分解して書くことができます。
/**
* @OA\Schema(
* schema="user_responder",
* required={"id", "name"}
* )
*/
class UserResponder extends BaseResponder
{
/**
* @OA\Property(
* property="id",
* type="integer",
* description="ユーザID",
* example="1"
* ),
*/
private $id;
/**
* @OA\Property(
* property="name",
* type="string",
* description="ユーザの名前",
* example="サンプル太郎"
* ),
*/
private $name;
required はそれぞれのプロパティに書くのではなくて、schemaに定義します。
配列を含むannotation
出力例
{
"news": [
{
"id": 5,
"title": "Synergy Night Fever 2019 ──国内ベンチャーシーンを牽引する経営者3名とM&Aについて語る イベントレポート",
"created_at": "2019-08-26T11:01:38+09:00"
},
{
"id": 4,
"title": "テスト",
"created_at": "2019-07-31T10:41:21+09:00"
},
]
}
annotation
/**
* @OA\Get(
* tags={"Media"},
* path="/api/news",
* @OA\Response(
* response="200",
* description="success",
* @OA\JsonContent(ref="#/components/schemas/news_list_responder")
* ),
* )
*/
呼び出される schema は以下のようになります。
/**
* @OA\Schema(
* schema="news_summary",
* required={"id", "title", "created_at"},
* @OA\Property(property="id", type="integer", example=1),
* @OA\Property(property="title", type="string", example="タイトル"),
* @OA\Property(property="created_at", type="string", example="2020-01-17T11:25:28+09:00"),
* )
*/
/**
* @OA\Schema(
* schema="news_list_responder",
* )
*/
class NewsListResponder extends BaseResponder
{
/**
* @OA\Property(
* property="news",
* type="array",
* @OA\Items(
* ref="#/components/schemas/news_summary"
* ),
* )
*/
private $news;
ちょっと複雑ですが、要するに、まずは list
の schema を呼び出して、property が配列なので、さらに別のschemaを呼び出しています。
array type の property の中で schema を定義せず全て子供の property を定義することも試したのですが、それは動きませんでした。ちょっとハマりどころ。
キーに対してオブジェクトを指定するannotation
出力例
{
"number_of_people_options": {
"1": "~5人",
"2": "5~10人"
},
"headquarter_location_options": {
"1": "北海道",
"2": "青森県"
}
}
annotation
/**
* @OA\Get(
* tags={"Common"},
* path="/api/options/info",
* @OA\Response(
* response="200",
* description="success",
* @OA\JsonContent(ref="#/components/schemas/info_options_responder")
* ),
* )
*/
/**
* @OA\Schema(
* schema="info_options_responder",
* type="object",
* required={"number_of_people_options", "headquarter_location_options"}
* )
*/
class InfoOptionsResponder extends BaseResponder
{
/**
* @OA\Property(
* property="number_of_people_options",
* type="object",
* example={1: "~5人", 2: "5~10人"}
* ),
*/
private $numberOfPeopleOptions;
/**
* @OA\Property(
* property="headquarter_location_options",
* type="object",
* example={1: "北海道", 2: "青森県"}
* ),
*/
private $headquarterLocationOptions;
schema においては object type を使用します。property の object の key value が固定であればさらに定義できますが、このケースのように固定じゃない場合には array が使えるかもしれません(この形は本運用でまだ使えていないので今後の宿題にして、かけたら更新します)。
終わりに
書き慣れるまでなかなか辛いです。慣れてしまうとパターンも少ないので案外サクサクかけます。
このannotationを使ったdocumentから実際のAPIレスポンスをテストできるのですが、それについては他の記事で書こうと思います。