APIリソース
- リソース コレクション
- 概念の概要
- コレクションを保護する鍵
- カスタマイズされた基本リソース クラス
- #ネストされたリソースのラップ
- ##データ ラップとページング ページング
- #条件付き属性
- 条件付き結合データ
- 条件付き中間テーブル情報
- トップレベルのメタデータ
- リソースの構築時にメタデータを追加する
- 対応リソース
雄弁: API リソース
##概要make:resource
Artisan コマンドを使用してリソース クラスを生成できます。デフォルトでは、生成されたリソースはアプリケーションの
app/Http/Resourcesフォルダーに配置されます。リソースは
Illuminate\Http\Resources\Json\JsonResourceから継承します。 クラス:
php artisan make:resource User
Resource Collection リソース変換用の単一モデルを生成するだけでなく、モデルのコレクションを変換するためのリソース コレクション。これにより、特定のリソースに関連するリンクやその他のメタ情報を応答に含めることができます。 リソースの生成時に--collection
フラグを追加してリソース コレクションを生成する必要があります。あるいは、リソース名に
Collectionを直接含めて、リソースのコレクションを生成する必要があることを Laravel に示すこともできます。リソース コレクションは
Illuminate\Http\Resources\Json\ResourceCollectionクラスから継承します:
php artisan make:resource Users --collection php artisan make:resource UserCollection
#コンセプトの概要## {ヒント} これは、リソースとリソース コレクションの概要です。リソースをより適切にカスタマイズおよび使用する方法について洞察を得るために、このドキュメントの他のセクションを読むことを強くお勧めします。
リソースをカスタムで記述する方法に入る前に、まず Laravel でリソースを使用する方法を見てみましょう。リソース クラスは、JSON 形式に変換する必要がある単一のモデルを表します。たとえば、単純なUser
各リソース クラスは、応答の送信時に should を返すリソース クラスができました。
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class User extends JsonResource{ /** * 将资源转换成数组。 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; } }
toArray
変数を直接使用してモデルのプロパティにアクセスできることに注意してください。これは、簡単にアクセスできるように、リソース クラスがプロパティとメソッドを基になるモデルに自動的にプロキシするためです。ルートまたはコントローラーで定義されたリソースを返すことができます。メソッドを定義します。 JSON に変換されたプロパティ。ここでは、
$thisuse App\User; use App\Http\Resources\User as UserResource; Route::get('/user', function () { return new UserResource(User::find(1)); });
リソース コレクション
ルートまたはコントローラーで
collection メソッドを使用して、リソース インスタンスを作成し、コレクションを返すことができます。複数のリソースまたはページ分割された応答:use App\User; use App\Http\Resources\User as UserResource; Route::get('/user', function () { return UserResource::collection(User::all()); });
もちろん、上記の方法を使用すると、追加のメタデータを追加してコレクションとともに返すことはできません。カスタム リソース コレクションの応答が必要な場合は、コレクションを表す専用のリソースを作成する必要があります:
php artisan make:resource UserCollection
生成されたリソース コレクション クラスの応答で返したいメタデータを簡単に定義できます:
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UserCollection extends ResourceCollection{ /** * 将资源集合转换成数组。 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return [ 'data' => $this->collection, 'links' => [ 'self' => 'link-value', ], ]; } }
定義済みのリソース コレクションをルートまたはコントローラーで返すことができます:
use App\User; use App\Http\Resources\UserCollection; Route::get('/users', function () { return new UserCollection(User::all()); });
コレクションのキーを保護する
ルートからリソース コレクションを返すとき、Laravel はコレクションのキーをリセットします。単純な番号順になっています。ただし、
preserveKeys
属性をリソース クラスに追加して、コレクション キーを保持するかどうかを示すことができます。<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class User extends JsonResource{ /** * 指示是否应保留资源的集合键。 * * @var bool */ public $preserveKeys = true; }
preserveKeys
属性が ## に設定されている場合#true、コレクションのキーは保護されます:
use App\User; use App\Http\Resources\User as UserResource; Route::get('/user', function () { return UserResource::collection(User::all()->keyBy->id); });
カスタマイズされた基本リソース クラス通常、リソース コレクションには自動的に値が設定されます。その結果、コレクションの各項目が個別のリソース クラスにマップされます。単一のリソース クラスはコレクションのクラス名とみなされますが、末尾のCollection
は、指定されたユーザー インスタンスを文字列は付きません。
たとえば、
UserCollectionUser
リソースにマップします。この動作をカスタマイズするには、リソース コレクションの
$collectsプロパティをオーバーライドします。
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UserCollection extends ResourceCollection{ /** * collects 属性定义了资源类。 * * @var string */ public $collects = 'App\Http\Resources\Member'; }
{ヒント}
概念の概要をまだ読んでいない場合は、このドキュメントを読み続ける前に読むことを強くお勧めします。
メソッドが含まれています。本質的に、リソースの役割は単純です。与えられたモデルを配列に変換するだけで済みます。したがって、各リソースには、モデルのプロパティをユーザーに返すことができる API フレンドリーな配列に変換する
toArray<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class User extends JsonResource{ /** * 将资源转换成数组。 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; } }
ルートまたはコントローラーで返すことができます すでに定義されていますリソース:
use App\User; use App\Http\Resources\User as UserResource; Route::get('/user', function () { return new UserResource(User::find(1)); });
Associations 関連リソースを応答に含める場合は、toArray
メソッドによって返される配列にそれらのリソースを追加するだけです。次の例では、Post
リソースの
collectionメソッドを使用して、ユーザーの投稿をリソース応答に追加します:
/** * 将资源转换成数组。 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request){ return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'posts' => PostResource::collection($this->posts), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
{tip}関連付けがすでに読み込まれている場合にのみ関連リソースを追加する場合は、条件付き関連付けのドキュメントを参照してください。
リソースは単一のモデルを配列に変換し、リソース コレクションは複数のモデルのコレクションを配列に変換します。すべてのリソースには、「一時的な」リソース コレクションを生成するためのリソース コレクション
collection
メソッドが用意されているため、モデル タイプごとにリソース コレクション クラスを記述する必要はありません。use App\User; use App\Http\Resources\User as UserResource; Route::get('/user', function () { return UserResource::collection(User::all()); });
ただし、必要な場合は、返されたコレクションのメタデータをカスタマイズするには、リソース コレクションを定義する必要があります:
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UserCollection extends ResourceCollection{ /** * 将资源集合转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return [ 'data' => $this->collection, 'links' => [ 'self' => 'link-value', ], ]; } }
単一リソースと同様に、ルートまたはコントローラーでリソース コレクションを直接返すことができます:use App\User; use App\Http\Resources\UserCollection; Route::get('/users', function () { return new UserCollection(User::all()); });
データ ラッピング
デフォルトでは、リソース応答が JSON に変換されると、トップレベルのリソースは
data
キーでラップされます。したがって、一般的なリソース コレクションの応答は次のようになります。{ "data": [ { "id": 1, "name": "Eladio Schroeder Sr.", "email": "therese28@example.com", }, { "id": 2, "name": "Liliana Mayert", "email": "evandervort@example.com", } ] }
リソース基本クラスの
withoutWrapping
メソッドを使用して、トップレベル リソースのラッピングを無効にできます。通常、このメソッドは、AppServiceProvider
またはプログラムのリクエストごとに読み込まれる他のサービス プロバイダーで呼び出す必要があります。<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Http\Resources\Json\Resource; class AppServiceProvider extends ServiceProvider{ /** * 在注册后进行服务的启动 * * @return void */ public function boot() { Resource::withoutWrapping(); } /** * 在容器中注册绑定 * * @return void */ public function register() { // } }
{note}
withoutWrappin
このメソッドは最上位リソースのラッピングを無効にするだけで、リソース コレクションに手動で追加したdata
キーは削除しません。ネストされたリソースのラップ
リソースの関連付けをどのようにラップするかを完全に自由に決定できます。すべてのリソース コレクションを、どれほどネストされているかに関係なく
data
キーでラップしたい場合は、リソースごとにリソース コレクション クラスを定義し、返されたコレクションをdata
でラップする必要があります。鍵。もちろん、トップレベルのリソースが 2 つの
data
キーでラップされるのではないかと心配するかもしれません。 Laravel ではリソースが二重にラップされることは決してないので、安心してください。そのため、変換されたリソースのコレクションが多重ネストになることを心配する必要はありません。<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class CommentsCollection extends ResourceCollection{ /** * 将资源集合转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return ['data' => $this->collection]; } }
データのラッピングとページネーション
Whenリソース応答でページ分割されたコレクションを返すとき、
withoutWrapping
メソッドを呼び出した場合でも、Laravel はリソースデータをdata
キーでラップします。これは、ページ分割された応答には、ページ分割ステータス情報を含むmeta
キーとlinks
キーが常に存在するためです。 # Paginationページネーション インスタンスをリソースの collection メソッドまたはカスタム リソース コレクションに渡すことができます:
{ "data": [ { "id": 1, "name": "Eladio Schroeder Sr.", "email": "therese28@example.com", }, { "id": 2, "name": "Liliana Mayert", "email": "evandervort@example.com", } ], "links":{ "first": "http://example.com/pagination?page=1", "last": "http://example.com/pagination?page=1", "prev": null, "next": null }, "meta":{ "current_page": 1, "from": 1, "last_page": 1, "path": "http://example.com/pagination", "per_page": 15, "to": 10, "total": 10 } }
ページネーション応答。および
linksキーにはページング ステータス情報が含まれます:
use App\User; use App\Http\Resources\UserCollection; Route::get('/users', function () { return new UserCollection(User::paginate()); });
whenisAdmin条件属性
give 特定の条件が満たされた場合にリソース応答に属性を追加します。たとえば、現在のユーザーが「管理者」の場合、リソース応答に値を追加することができます。この場合、Laravel は問題の解決に役立ついくつかのヘルパー メソッドを提供します。
メソッドが
true# を返した場合のみです。 ##、secret
を返した場合、リソース応答がクライアントに送信される前にキーは最終的にリソース応答で返されます。このメソッドが
falsesecret
キーが削除されます。
whenメソッドを使用すると、配列を連結するための条件ステートメントの使用を回避し、代わりにより洗練された方法でリソースを作成できます。
when
メソッドは 2 番目のパラメータとしてクロージャも受け入れます。戻り値は、指定された条件が
true:
の場合にのみクロージャから計算されます。/** * 将资源转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request){ return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'secret' => $this->when(Auth::user()->isAdmin(), 'secret-value'), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
条件付きでのデータのマージ
特定の条件が満たされたときに、リソース応答に複数の属性を追加したい場合があります。この場合、指定された条件が
true
の場合、mergeWhen
メソッドを使用して応答に複数の属性を追加できます。'secret' => $this->when(Auth::user()->isAdmin(), function () { return 'secret-value'; }),
同様に、指定された条件が
false
、これらの属性は、リソース応答がクライアントに送信される前に削除されます。{note}
mergeWhen
メソッドは、文字列キーと数値キーが混在する配列では使用しないでください。さらに、連続していない数値キーの配列では使用しないでください。条件付き関連付け
プロパティを条件付きで追加するだけでなく、モデルの関連付けが既に行われているかどうかに基づいてプロパティを条件付きで追加することもできます。リソース応答に関連付けを含めます。これにより、どのモデル関連付けをロードするかをコントローラーで決定できるため、リソースはモデル関連付けがロードされた後にのみモデル関連付けを追加できるようになります。
これを行うと、リソース内の「N 1」クエリの問題が回避されます。条件付きで関連付けを読み込むには、
whenLoaded
メソッドを使用する必要があります。不要な関連付けのロードを避けるために、このメソッドは関連付け自体ではなく関連付けの名前をパラメータとして受け入れます。/** * 将资源转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request){ return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, $this->mergeWhen(Auth::user()->isAdmin(), [ 'first-secret' => 'value', 'second-secret' => 'value', ]), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
上の例では、関連付けがロードされていない場合、
posts
key は、リソース応答がクライアントに送信される前に削除されます。条件付き中間テーブル情報
リソース応答に関連付けを条件付きで含めるだけでなく、
whenPivotLoaded
メソッドを使用して多対多の条件付き結合を行うこともできます。データを中間テーブルにコピーします。whenPivotLoaded
このメソッドで受け入れられる最初のパラメータは、中間テーブルの名前です。 2 番目のパラメーターは、モデルで中間テーブル情報が利用可能な場合に返される値を定義するクロージャです。/** * 将资源转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request){ return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'posts' => PostResource::collection($this->whenLoaded('posts')), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
中間テーブルが
pivot
アクセサー以外のものを使用している場合、次のことができます。whenPivotLoadedAs
メソッドを使用します:/** * 将资源转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request){ return [ 'id' => $this->id, 'name' => $this->name, 'expires_at' => $this->whenPivotLoaded('role_user', function () { return $this->pivot->expires_at; }), ]; }
メタデータの追加
一部の JSON API 標準では、リソースにメタデータを追加する必要があります。リソース収集の応答。これには通常、リソースまたは関連リソースの
リンク
、またはリソース自体に関するメタデータが含まれます。リソースに関する追加のメタデータを返す必要がある場合は、それらをtoArray
メソッドに含めるだけです。たとえば、リソースのコレクションを変換する場合、links
情報を追加する必要がある場合があります:/** * 将资源转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request){ return [ 'id' => $this->id, 'name' => $this->name, 'expires_at' => $this->whenPivotLoadedAs('subscription', 'role_user', function () { return $this->subscription->expires_at; }), ]; }
リソースに追加のメタデータを追加する場合、ページ分割されたデータを返すときに Laravel を上書きすることを心配する必要はありません。
links
またはmeta
キーが自動的に追加されました。追加した他のlinks
は、ページ分割された応答によって追加されたlinks
とマージされます。トップレベルのメタデータ
リソースがトップレベルのリソースとして返されるときに、リソース応答にメタデータを追加したい場合があります。通常、これには応答全体に関するメタ情報が含まれます。
with
メソッドをリソース クラスに追加して、メタデータを定義できます。このメソッドは、リソースがトップレベルのリソースとしてレンダリングされるときにリソース応答に含まれるメタデータの配列を返す必要があります。/** * 将资源转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request){ return [ 'data' => $this->collection, 'links' => [ 'self' => 'link-value', ], ]; }
リソースの構築時にメタデータを追加します
あなたもトップ-level データは、ルートまたはコントローラーでリソース インスタンスを構築するときに追加できます。すべてのリソースは、
Additional
メソッドを使用して、リソース応答に追加する必要があるデータの配列を受け入れることができます:<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UserCollection extends ResourceCollection{ /** * 将资源集合转换成数组 * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return parent::toArray($request); } /** * 返回应该和资源一起返回的其他数据数组 * * @param \Illuminate\Http\Request $request * @return array */ public function with($request) { return [ 'meta' => [ 'key' => 'value', ], ]; } }
Response Resources
ご存知のとおり、リソースはルートとコントローラーで直接返すことができます:
return (new UserCollection(User::all()->load('roles'))) ->additional(['meta' => [ 'key' => 'value', ] ]);
ただし、場合によっては、HTTP 応答をクライアントに送信する前にカスタマイズする必要があります。選択肢は 2 つあります。まず、チェーン上で
response
メソッドを呼び出すことができます。このメソッドはIlluminate\Http\Response
インスタンスを返し、応答ヘッダー情報をカスタマイズできます。use App\User; use App\Http\Resources\User as UserResource; Route::get('/user', function () { return new UserResource(User::find(1)); });
さらに、
withResponse
を定義することもできます。リソースメソッド。このメソッドは、リソースが応答として最上位リソースとして使用されるときに呼び出されます。use App\User; use App\Http\Resources\User as UserResource; Route::get('/user', function () { return (new UserResource(User::find(1))) ->response() ->header('X-Value', 'True'); });
この記事は、LearnKu.com Web サイトで最初に公開されました。