概要
- laravel-openapiにて一括してexampleを定義する方法をまとめる。
前提
-
exampleの定義は各スキーマ毎に定義していた。
-
今回はexampleを個別にではなく一括で定義してみようと思う。
準備
-
下記のように各ファイルを定義した。
-
ルーティング
アプリ名ディレクトリ/routes/api.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\UserController; /* |-------------------------------------------------------------------------- | API Routes |-------------------------------------------------------------------------- | | Here is where you can register API routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | is assigned the "api" middleware group. Enjoy building your API! | */ Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); }); Route::post('/update', [UserController::class, 'update']);
-
コントローラー
アプリ名ディレクトリ/app/Http/Controllers/UserController.php<?php namespace App\Http\Controllers; use App\OpenApi\RequestBodies\UserUpdateRequestBody; use Vyuldashev\LaravelOpenApi\Attributes as OpenApi; #[OpenApi\PathItem] class UserController extends Controller { /** * ユーザー情報更新 * * @return void */ #[OpenApi\Operation] #[OpenApi\RequestBody(UserUpdateRequestBody::class)] public function update() { } }
-
laravel-requestリクエストボディー
アプリ名ディレクトリ/app/OpenApi/RequestBodies/UserUpdateRequestBody.php<?php namespace App\OpenApi\RequestBodies; use App\OpenApi\Schemas\UserUpdateRequestBodySchema; use GoldSpecDigital\ObjectOrientedOAS\Objects\MediaType; use GoldSpecDigital\ObjectOrientedOAS\Objects\RequestBody; use Vyuldashev\LaravelOpenApi\Factories\RequestBodyFactory; class UserUpdateRequestBody extends RequestBodyFactory { public function build(): RequestBody { return RequestBody::create() ->content( MediaType::json() ->schema(UserUpdateRequestBodySchema::ref()) ); } }
-
laravel-requestリクエストボディースキーマ
アプリ名ディレクトリ/app/OpenApi/Schemas/UserUpdateRequestSchema.php<?php namespace App\OpenApi\Schemas; use GoldSpecDigital\ObjectOrientedOAS\Contracts\SchemaContract; use GoldSpecDigital\ObjectOrientedOAS\Objects\AllOf; use GoldSpecDigital\ObjectOrientedOAS\Objects\AnyOf; use GoldSpecDigital\ObjectOrientedOAS\Objects\Not; use GoldSpecDigital\ObjectOrientedOAS\Objects\OneOf; use GoldSpecDigital\ObjectOrientedOAS\Objects\Schema; use Vyuldashev\LaravelOpenApi\Contracts\Reusable; use Vyuldashev\LaravelOpenApi\Factories\SchemaFactory; class UserUpdateRequestBodySchema extends SchemaFactory implements Reusable { /** * @return AllOf|OneOf|AnyOf|Not|Schema */ public function build(): SchemaContract { return Schema::object('UserUpdateRequestBody') ->properties( Schema::integer('id') ->description('ユーザーID') ->example(1), Schema::string('name') ->description('ユーザー名') ->example('XXX YYY'), Schema::string('email') ->description('ユーザーメールアドレス') ->example('test@example.com'), Schema::array('foo_infos') ->items( Schema::object() ->properties( Schema::integer('id') ->description('ID') ->example(1), Schema::string('info') ->description('情報') ->example('hoge hoge'), ) ) ); } }
-
-
上記の状態でOpenAPIを出力したところ下記の内容が出力された。
{ "openapi": "3.0.2", "info": { "title": "Laravel", "version": "1.0.0" }, "servers": [ { "url": "http:\/\/localhost" } ], "paths": { "\/api\/update": { "post": { "summary": "ユーザー情報更新", "requestBody": { "content": { "application\/json": { "schema": { "$ref": "#\/components\/schemas\/UserUpdateRequestBody" } } } } } } }, "components": { "schemas": { "UserUpdateRequestBody": { "type": "object", "properties": { "id": { "description": "ユーザーID", "type": "integer", "example": 1 }, "name": { "description": "ユーザー名", "type": "string", "example": "XXX YYY" }, "email": { "description": "ユーザーメールアドレス", "type": "string", "example": "test@example.com" }, "foo_infos": { "type": "array", "items": { "type": "object", "properties": { "id": { "description": "ID", "type": "integer", "example": 1 }, "info": { "description": "情報", "type": "string", "example": "hoge hoge" } } } } } } } } }
方法
-
下記のようなJSONのexampleを一括して定義したい。
{ "id": 10, "name": "AAA BBB", "email": "testtest@example.com", "foo_infos": [ { "id": 100, "info": "fuga fuga" }, { "id": 200, "info": "piyo piyo" } ] }
-
スキーマクラスを下記のように記載する。
アプリ名ディレクトリ/app/OpenApi/Schemas/UserUpdateRequestSchema.php<?php namespace App\OpenApi\Schemas; use GoldSpecDigital\ObjectOrientedOAS\Contracts\SchemaContract; use GoldSpecDigital\ObjectOrientedOAS\Objects\AllOf; use GoldSpecDigital\ObjectOrientedOAS\Objects\AnyOf; use GoldSpecDigital\ObjectOrientedOAS\Objects\Not; use GoldSpecDigital\ObjectOrientedOAS\Objects\OneOf; use GoldSpecDigital\ObjectOrientedOAS\Objects\Schema; use Vyuldashev\LaravelOpenApi\Contracts\Reusable; use Vyuldashev\LaravelOpenApi\Factories\SchemaFactory; class UserUpdateRequestBodySchema extends SchemaFactory implements Reusable { /** * @return AllOf|OneOf|AnyOf|Not|Schema */ public function build(): SchemaContract { return Schema::object('UserUpdateRequestBody') ->properties( Schema::integer('id') ->description('ユーザーID') ->example(1), Schema::string('name') ->description('ユーザー名') ->example('XXX YYY'), Schema::string('email') ->description('ユーザーメールアドレス') ->example('test@example.com'), Schema::array('foo_infos') ->items( Schema::object() ->properties( Schema::integer('id') ->description('ID') ->example(1), Schema::string('info') ->description('情報') ->example('hoge hoge'), ) ) ) ->example([ 'id' => 10, 'name' => 'AAA BBB', 'email' => 'testtest@example.com', 'foo_infos' => [ [ 'id' => 100, 'info' => 'fuga fuga', ], [ 'id' => 200, 'info' => 'piyo piyo', ], ], ]); } }
-
下記のようなJSONが出力された。
{ "openapi": "3.0.2", "info": { "title": "Laravel", "version": "1.0.0" }, "servers": [ { "url": "http:\/\/localhost" } ], "paths": { "\/api\/update": { "post": { "summary": "ユーザー情報更新", "requestBody": { "content": { "application\/json": { "schema": { "$ref": "#\/components\/schemas\/UserUpdateRequestBody" } } } } } } }, "components": { "schemas": { "UserUpdateRequestBody": { "type": "object", "properties": { "id": { "description": "ユーザーID", "type": "integer", "example": 1 }, "name": { "description": "ユーザー名", "type": "string", "example": "XXX YYY" }, "email": { "description": "ユーザーメールアドレス", "type": "string", "example": "test@example.com" }, "foo_infos": { "type": "array", "items": { "type": "object", "properties": { "id": { "description": "ID", "type": "integer", "example": 1 }, "info": { "description": "情報", "type": "string", "example": "hoge hoge" } } } } }, "example": { "id": 10, "name": "AAA BBB", "email": "testtest@example.com", "foo_infos": [ { "id": 100, "info": "fuga fuga" }, { "id": 200, "info": "piyo piyo" } ] } } } } }
-
Swagger Viewerで確認すると下記のようにExample Valueには一括で設定したexampleが表示されている。
-
Schemaの方は個々で割当たexampleが表示されている。