9
4

More than 3 years have passed since last update.

swagger-php で書く Annotation テンプレ3種

Last updated at Posted at 2020-03-16

この記事は、温かみのある手作業で 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レスポンスをテストできるのですが、それについては他の記事で書こうと思います。

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4