Laravelとl5-Swaggerを使用してAPIドキュメントを作成する

l5-Swaggerは、OpenAPI仕様のSwaggerをAをLaravelで使えるようにしたライブラリです。
l5-Swaggerを使うことで簡単にAPIドキュメントを作成することができます。

ライブラリのインストール

今回Laravelのバージョンは9系を使用します。
以下のコマンドを叩きライブラリをインストールします。

composer require "darkaonline/l5-swagger"

コントローラーにAPI情報は共通スキーマを記述する

API情報やサーバー情報、共通スキーマはコントローラの中であればどこでもいいのですが
/app/Http/Controllers/Swagger.phpなどを作成して記述すルトわかりやすくていいと思います。

<?php

namespace App\Http\Controllers\Api;

/**
 * API情報
 * @OA\Info(
 *     version="1.0.0",
 *     title="My Project",
 *     description="Sample system"
 * )
 *
 * サーバー情報
 * @OA\Server(
 *   description="OpenApi host",
 *   url="http://localhost"
 * )
 *
 * セキュリティスキーマ
 * @OA\SecurityScheme(
 *   securityScheme="BearerAuth",
 *   type="apiKey",
 *   in="header",
 *   name="api_token"
 * )
 */
class Swagger
{
}

GETリクエストとPOSTリクエストのドキュメント

GETとPOSTリクエストのドキュメントの具体的な例を示します。
これらのアノテーションはControllerに直接追加します。

GETリクエスト

ここではBooksControllerがある場合の例を書きます

/**
 * @OA\Get(
 *      path="/api/books",
 *      operationId="getBooksList",
 *      tags={"Books"},
 *      summary="Get list of books",
 *      description="Returns list of books",
 *      @OA\Parameter(
 *          name="author",
 *          in="query",
 *          description="Filter books by the author's name",
 *          required=false,
 *          @OA\Schema(
 *              type="string"
 *          ),
 *          example="John Doe"
 *      ),
 *      @OA\Response(
 *          response=200,
 *          description="Successful operation"
 *       ),
 *       @OA\Response(
 *          response=404,
 *          description="Not Found"
 *       ),
 * )
 */
public function index()
{
    // Get the list of books from the database
    // return as a response
}
アノテーション要素説明
@OA\GetHTTP GETリクエストを表す。エンドポイントのHTTPメソッドを定義します。
pathAPIエンドポイントのパスを指定します。例:”/api/books”
operationIdオペレーションを一意に識別するためのID。任意の文字列を設定できますが、一意であることが重要です。
tagsAPIエンドポイントを分類するためのタグ。例:”Books”
summaryAPIエンドポイントの短い概要。
descriptionAPIエンドポイントの詳細な説明。
@OA\ParameterAPIエンドポイントが要求する可能性があるパラメータを定義。
name (Parameter内)パラメータの名前を指定。例:”author”
in (Parameter内)パラメータの場所を指定。例:”query” (クエリストリングとして送られる)
description (Parameter内)パラメータの説明。
required (Parameter内)パラメータが必須かどうかを示す。例:”false” (このパラメータはオプション)
@OA\Schemaパラメータの型を定義。例:”string”
example (Schema内)パラメータの具体的な例を提供。例:”John Doe”
@OA\Response可能なHTTPレスポンスを定義。
response (Response内)HTTPステータスコード。
description (Response内)レスポンスの説明。複数のレスポンスを定義することが可能。

POSTリクエスト

/**
 * @OA\Post(
 *      path="/api/books",
 *      operationId="storeBook",
 *      tags={"Books"},
 *      summary="Store new book",
 *      description="Returns book data",
 *      @OA\RequestBody(
 *          required=true,
 *          @OA\JsonContent(ref="#/components/schemas/StoreBookRequest")
 *      ),
 *      @OA\Response(
 *          response=201,
 *          description="Successful operation",
 *      ),
 *      @OA\Response(
 *          response=400,
 *          description="Bad Request",
 *      ),
 * )
 */
public function store(Request $request)
{
    // Validate and store the new book in the database
    // return the book data as a response
}
アノテーション要素説明
@OA\PostHTTP POSTリクエストを表す。エンドポイントのHTTPメソッドを定義します。
@OA\RequestBodyAPIエンドポイントが要求するリクエストボディを定義します。
required (RequestBody内)このリクエストボディが必須であることを示します。例:”true”
@OA\JsonContentリクエストボディの内容を表すJSONスキーマを定義。
ref (JsonContent内)定義済みのスキーマを参照。例:”#/components/schemas/StoreBookRequest”

定義済みスキーマとは

先ほどのPOSTリクエストで参照した定義済みスキーマとはここでは再利用可能なデータ構造の説明やモデルのことを言います。
スキーマは一度定義することで、ドキュメント全体で参照し再利用することが可能になるのでコードの重複を減らすことができます。
以下のスキーマはこ、新しい本を追加するリクエストボディがどのような形式であるべきかを定義しています。この例では、titleauthorの2つのプロパティが必須と定義され、それぞれに対して説明と具体的な例が提供されています。

/**
 * @OA\Schema(
 *     schema="StoreBookRequest",
 *     type="object",
 *     required={"title", "author"},
 *     @OA\Property(
 *         property="title",
 *         type="string",
 *         description="The title of the book",
 *         example="Moby Dick"
 *     ),
 *     @OA\Property(
 *         property="author",
 *         type="string",
 *         description="The author of the book",
 *         example="Herman Melville"
 *     )
 * )
 */

APIドキュメントの生成

php artisan l5-swagger:generate

上記のコマンドを叩くと/path/to/project/storage/api-docs/api-docs.jsonが生成される。
.envに下記を設定すれば毎回コマンドをたたかなくても更新されるようになります。

L5_SWAGGER_GENERATE_ALWAYS=true

またyamlファイルでも生成したい場合は以下を.envに追記します。

L5_SWAGGER_GENERATE_YAML_COPY=ture
L5_FORMAT_TO_USE_FOR_DOCS=yaml

以下のURLからドキュメントを確認しましょう。

http://localhost:8000/api/documentation

設定をカスタマイズするには

設定のカスタマイズをしたい場合には以下のコマンドを叩きconfig/l5-swagger.php ファイルを
作成して設定を変えることでカスタマイズすることが可能となります。

php artisan vendor:publish --provider "L5Swagger\L5SwaggerServiceProvider"

エラーになった記述方法

l5-swaggerではOA\Infoを定義したクラスには必ずOA\GetやOA\PutといったAPIをセットで定義しなければならないようで定義していないと以下のエラーが出ます。

Required @OA\PathItem() not found

また以下のようにAPIを定義していたとしてもメソッドのすぐ上にPHPDocを書いていた場合上記のエラーが出ました。
なのでPHPDocは消してしまうかアノテーションの上に書くようにしなければなりませんでした。

/**
 * @OA\Get(
 *     path="/api/users",
 *     @OA\Response(response="200", description="An example endpoint")
 * )
 */
/**
 * get user
 *
 * @return \Illuminate\Http\JsonResponse
 */
 public function getUsers() {
    ...
 }

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。