Readouble

Laravel 9.x Eloquent:APIリソース

イントロダクションIntroduction

APIを構築する場合、Eloquentモデルと実際にアプリケーションのユーザーへ返すJSONレスポンスの間に変換レイヤーが必要になるでしょう。たとえば、ユーザーのサブセットに対して特定の属性を表示し、他のユーザーには表示したくない場合や、モデルのJSON表現に常に特定のリレーションを含めたい場合などです。Eloquentのリソースクラスを使用すると、モデルとモデルコレクションを表現力豊かかつ簡単にJSONに変換できます。When building an API, you may need a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application's users. For example, you may wish to display certain attributes for a subset of users and not others, or you may wish to always include certain relationships in the JSON representation of your models. Eloquent's resource classes allow you to expressively and easily transform your models and model collections into JSON.

もちろん、toJsonメソッドを使用してEloquentモデルまたはコレクションをJSONへいつでも変換できます。ただし、Eloquentリソースは、モデルのJSONシリアル化とそれらの関係をよりきめ細かく堅牢に制御します。Of course, you may always convert Eloquent models or collections to JSON using their toJson methods; however, Eloquent resources provide more granular and robust control over the JSON serialization of your models and their relationships.

リソースの生成Generating Resources

リソースクラスを生成するには、make:resource Artisanコマンドを使用します。リソースはアプリケーションのapp/Http/Resourcesディレクトリにデフォルトで配置されます。リソースはIlluminate\Http\Resources\Json\JsonResourceクラスを拡張します。To generate a resource class, you may use the make:resource Artisan command. By default, resources will be placed in the app/Http/Resources directory of your application. Resources extend the Illuminate\Http\Resources\Json\JsonResource class:

php artisan make:resource UserResource

リソースコレクションResource Collections

個々のモデルを変換するリソースを生成することに加えて、モデルのコレクションの変換を担当するリソースを生成することもできます。これにより、JSONレスポンスへ指定するリソースのコレクション全体へ関連するリンクやその他のメタ情報を含められます。In addition to generating resources that transform individual models, you may generate resources that are responsible for transforming collections of models. This allows your JSON responses to include links and other meta information that is relevant to an entire collection of a given resource.

リソースコレクションを生成するには、リソースを生成するときに--collectionフラグを使用する必要があります。または、リソース名にCollectionという単語を含めると、コレクションリソースを作成する必要があるとLaravelに指示できます。コレクションリソースは、Illuminate\Http\Resources\JSON\ResourceCollectionクラスを拡張します。To create a resource collection, you should use the --collection flag when creating the resource. Or, including the word Collection in the resource name will indicate to Laravel that it should create a collection resource. Collection resources extend the Illuminate\Http\Resources\Json\ResourceCollection class:

php artisan make:resource User --collection

php artisan make:resource UserCollection

概論Concept Overview

lightbulb Note:これは、リソースとリソースコレクションの概要です。リソースによって提供されるカスタマイズとパワーをより深く理解するために、このドキュメントの他のセクションも読むことを強く推奨します。Note
This is a high-level overview of resources and resource collections. You are highly encouraged to read the other sections of this documentation to gain a deeper understanding of the customization and power offered to you by resources.

リソースを作成するときに利用できるすべてのオプションに飛び込む前に、まずLaravel内でリソースがどのように使用されているかを大まかに見てみましょう。リソースクラスは、JSON構造に変換する必要がある単一のモデルを表します。たとえば、以下は単純なUserResourceリソースクラスです。Before diving into all of the options available to you when writing resources, let's first take a high-level look at how resources are used within Laravel. A resource class represents a single model that needs to be transformed into a JSON structure. For example, here is a simple UserResource resource class:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource 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,
        ];
    }
}

リソースをルートまたはコントローラメソッドからのレスポンスとして返すときにJSONへ変換する必要があるため、属性の配列を返すtoArrayメソッドをすべてのリソースクラスで定義します。Every resource class defines a toArray method which returns the array of attributes that should be converted to JSON when the resource is returned as a response from a route or controller method.

$this変数からモデルのプロパティに直接アクセスできることに注意してください。これは、リソースクラスがプロパティとメソッドのアクセスを基になるモデルに自動的にプロキシしており、アクセスを便利にしているためです。リソースを定義したら、ルートまたはコントローラから返せます。リソースは、コンストラクターを介して基になるモデルインスタンスを受け入れます。Note that we can access model properties directly from the $this variable. This is because a resource class will automatically proxy property and method access down to the underlying model for convenient access. Once the resource is defined, it may be returned from a route or controller. The resource accepts the underlying model instance via its constructor:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/user/{id}', function ($id) {
    return new UserResource(User::findOrFail($id));
});

リソースコレクションResource Collections

リソースのコレクションまたはページ分割されたレスポンスを返す場合は、ルートまたはコントローラでリソースインスタンスを作成するときに、リソースクラスによって提供されるcollectionメソッドを使用する必要があります。If you are returning a collection of resources or a paginated response, you should use the collection method provided by your resource class when creating the resource instance in your route or controller:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/users', function () {
    return UserResource::collection(User::all());
});

これでは、コレクションとともに返す必要のあるカスタムメタデータがある場合でもそれらを追加できないことに注意してください。リソースコレクションのレスポンスをカスタマイズする場合は、コレクションを表す専用のリソースを生成してください。Note that this does not allow any addition of custom meta data that may need to be returned with your collection. If you would like to customize the resource collection response, you may create a dedicated resource to represent the collection:

php artisan make:resource UserCollection

リソースコレクションクラスを生成したら、レスポンスに含める必要のあるメタデータを簡単に定義できます。Once the resource collection class has been generated, you may easily define any meta data that should be included with the response:

<?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',
            ],
        ];
    }
}

リソースコレクションを定義したら、ルートまたはコントローラから返せます。After defining your resource collection, it may be returned from a route or controller:

use App\Http\Resources\UserCollection;
use App\Models\User;

Route::get('/users', function () {
    return new UserCollection(User::all());
});

コレクションキーの保存Preserving Collection Keys

あるルートからリソースコレクションを返す場合、Laravelはコレクションのキーをリセットして番号順に並べます。しかし、コレクションの元のキーを保持する必要があるかどうかを示すpreserveKeysプロパティをリソースクラスに追加できます。When returning a resource collection from a route, Laravel resets the collection's keys so that they are in numerical order. However, you may add a preserveKeys property to your resource class indicating whether a collection's original keys should be preserved:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * リソースのコレクションキーを保持する必要がある事を示す
     *
     * @var bool
     */
    public $preserveKeys = true;
}

preserveKeysプロパティがtrueに設定されている場合、コレクションをルートまたはコントローラから返すとき、コレクションのキーが保持されます。When the preserveKeys property is set to true, collection keys will be preserved when the collection is returned from a route or controller:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/users', function () {
    return UserResource::collection(User::all()->keyBy->id);
});

基礎となるリソースクラスのカスタマイズCustomizing The Underlying Resource Class

通常、リソースコレクションの$this->collectionプロパティへは、コレクションの各アイテムをその単一のリソースクラスにマッピングした結果を自動的に代入します。単一のリソースクラスは、クラス名の末尾からCollection部分除いたコレクションのクラス名であると想定します。さらに、個人的な好みにもよりますが、単数形のリソースクラスには、Resourceというサフィックスが付いていてもいなくてもかまいません。Typically, the $this->collection property of a resource collection is automatically populated with the result of mapping each item of the collection to its singular resource class. The singular resource class is assumed to be the collection's class name without the trailing Collection portion of the class name. In addition, depending on your personal preference, the singular resource class may or may not be suffixed with Resource.

たとえば、UserCollectionは指定ユーザーインスタンスをUserResourceリソースにマップしようとします。この動作をカスタマイズするには、リソースコレクションの$collectsプロパティをオーバーライドします。For example, UserCollection will attempt to map the given user instances into the UserResource resource. To customize this behavior, you may override the $collects property of your resource collection:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * このリソースが収集するリソース
     *
     * @var string
     */
    public $collects = Member::class;
}

リソースの記述Writing Resources

lightbulb Note:概論を読んでいない場合は、このドキュメント読み進める前に一読することを強く推奨します。Note
If you have not read the concept overview[#concept-overview], you are highly encouraged to do so before proceeding with this documentation.

本質的に、リソースは単純です。特定のモデルを配列に変換するだけで済みます。したがって、各リソースには、モデルの属性をアプリケーションのルートまたはコントローラから返すことができるAPIフレンドリーな配列に変換するtoArrayメソッドが含まれています。In essence, resources are simple. They only need to transform a given model into an array. So, each resource contains a toArray method which translates your model's attributes into an API friendly array that can be returned from your application's routes or controllers:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource 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,
        ];
    }
}

リソースを定義したら、ルートまたはコントローラから直接返せます。Once a resource has been defined, it may be returned directly from a route or controller:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/user/{id}', function ($id) {
    return new UserResource(User::findOrFail($id));
});

リレーションRelationships

リレーションをレスポンスへ含めたい場合は、リソースのtoArrayメソッドから返す配列にそれらを追加できます。この例では、PostResourceリソースのcollectionメソッドを使用して、ユーザーのブログ投稿をリソースレスポンスへ追加しています。If you would like to include related resources in your response, you may add them to the array returned by your resource's toArray method. In this example, we will use the PostResource resource's collection method to add the user's blog posts to the resource response:

use App\Http\Resources\PostResource;

/**
 * リソースを配列に変換
 *
 * @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,
    ];
}

lightbulb Note:リレーションがすでにロードされている場合にのみリレーションを含めたい場合は、条件付きリレーションのドキュメントを確認してください。Note
If you would like to include relationships only when they have already been loaded, check out the documentation on conditional relationships[#conditional-relationships].

リソースコレクションResource Collections

リソースは単一のモデルを配列に変換しますが、リソースコレクションはモデルのコレクションを配列に変換します。ただし、すべてのリソースが「アドホック」リソースコレクションを簡単に生成するためにcollectionメソッドを提供しているため、モデルごとにリソースコレクションクラスを定義する必要はありません。While resources transform a single model into an array, resource collections transform a collection of models into an array. However, it is not absolutely necessary to define a resource collection class for each one of your models since all resources provide a collection method to generate an "ad-hoc" resource collection on the fly:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/users', function () {
    return UserResource::collection(User::all());
});

ただし、コレクションとともに返されるメタデータをカスタマイズする必要がある場合は、独自のリソースコレクションを定義する必要があります。However, if you need to customize the meta data returned with the collection, it is necessary to define your own resource collection:

<?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',
            ],
        ];
    }
}

単一のリソースと同様に、リソースコレクションはルートまたはコントローラから直接返されるでしょう。Like singular resources, resource collections may be returned directly from routes or controllers:

use App\Http\Resources\UserCollection;
use App\Models\User;

Route::get('/users', function () {
    return new UserCollection(User::all());
});

データのラップData Wrapping

デフォルトでは、リソースレスポンスがJSONに変換されるときに、最も外側のリソースがdataキーでラップされます。したがって、たとえば、一般的なリソースコレクションのレスポンスは次のようになります。By default, your outermost resource is wrapped in a data key when the resource response is converted to JSON. So, for example, a typical resource collection response looks like the following:

{
    "data": [
        {
            "id": 1,
            "name": "Eladio Schroeder Sr.",
            "email": "therese28@example.com"
        },
        {
            "id": 2,
            "name": "Liliana Mayert",
            "email": "evandervort@example.com"
        }
    ]
}

dataの代わりにカスタムキーを使用したい場合は、リソースクラスに$wrap属性を定義します。If you would like to use a custom key instead of data, you may define a $wrap attribute on the resource class:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * 適用する「データ」ラッパー
     *
     * @var string|null
     */
    public static $wrap = 'user';
}

最も外側のリソースのラッピングを無効にする場合は、ベースのIlluminate\Http\Resources\Json\JsonResourceクラスでwithoutWrappingメソッドを呼び出す必要があります。通常、このメソッドは、アプリケーションへのすべてのリクエストで読み込まれるAppServiceProviderか、別のサービスプロバイダから呼び出す必要があります。If you would like to disable the wrapping of the outermost resource, you should invoke the withoutWrapping method on the base Illuminate\Http\Resources\Json\JsonResource class. Typically, you should call this method from your AppServiceProvider or another service provider[/docs/{{version}}/providers] that is loaded on every request to your application:

<?php

namespace App\Providers;

use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 全アプリケーションサービスの登録
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * アプリケーションサービスの全初期起動処理
     *
     * @return void
     */
    public function boot()
    {
        JsonResource::withoutWrapping();
    }
}

warning Warning! withoutWrappingメソッドは最も外側のレスポンスにのみ影響し、独自のリソースコレクションに手作業で追加したdataキーは削除しません。Warning
The withoutWrapping method only affects the outermost response and will not remove data keys that you manually add to your own resource collections.

ネストされたリソースのラップWrapping Nested Resources

リソースのリレーションをどのようにラップするか、決定する完全な自由が皆さんにあります。ネストに関係なくすべてのリソースコレクションをdataキーでラップする場合は、リソースごとにリソースコレクションクラスを定義し、dataキー内でコレクションを返す必要があります。You have total freedom to determine how your resource's relationships are wrapped. If you would like all resource collections to be wrapped in a data key, regardless of their nesting, you should define a resource collection class for each resource and return the collection within a data key.

これにより、もっとも外側のリソースが2つのdataキーにラップされてしまうのか疑問に思われるかもしれません。心配ありません。Laravelが誤ってリソースを二重にラップすることは決してないので、変換するリソースコレクションのネストレベルについて心配する必要はありません。You may be wondering if this will cause your outermost resource to be wrapped in two data keys. Don't worry, Laravel will never let your resources be accidentally double-wrapped, so you don't have to be concerned about the nesting level of the resource collection you are transforming:

<?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];
    }
}

データのラップとペジネーションData Wrapping And Pagination

リソースレスポンスを介してページ付けされたコレクションを返す場合、LaravelはwithoutWrappingメソッドが呼び出された場合でも、リソースデータをdataキーでラップします。これはページ化されたレスポンスには、常にページネーターの状態に関する情報を含むmetaキーとlinksキーが含まれているためです。When returning paginated collections via a resource response, Laravel will wrap your resource data in a data key even if the withoutWrapping method has been called. This is because paginated responses always contain meta and links keys with information about the paginator's state:

{
    "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
    }
}

ペジネーションPagination

Laravel ペジネータインスタンスをリソースのcollectionメソッドまたはカスタムリソースコレクションに渡すことができます。You may pass a Laravel paginator instance to the collection method of a resource or to a custom resource collection:

use App\Http\Resources\UserCollection;
use App\Models\User;

Route::get('/users', function () {
    return new UserCollection(User::paginate());
});

ページ化されたレスポンスには、常に、ページネーターの状態に関する情報を含むmetaキーとlinksキーが含まれます。Paginated responses always contain meta and links keys with information about the paginator's state:

{
    "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
    }
}

条件付き属性Conditional Attributes

特定の条件が満たされた場合にのみ、リソースレスポンスに属性を含めたい場合があるでしょう。たとえば、現在のユーザーが「管理者(administrator)」である場合にのみ値を含めることができます。Laravelはこうした状況で、皆さんを支援するためのさまざまなヘルパメソッドを提供します。whenメソッドを使用して、リソースレスポンスに属性を条件付きで追加できます。Sometimes you may wish to only include an attribute in a resource response if a given condition is met. For example, you may wish to only include a value if the current user is an "administrator". Laravel provides a variety of helper methods to assist you in this situation. The when method may be used to conditionally add an attribute to a resource response:

/**
 * リソースを配列に変換
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'secret' => $this->when($request->user()->isAdmin(), 'secret-value'),
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

この例では、認証済みユーザーのisAdminメソッドがtrueを返した場合にのみ、最終的なリソースレスポンスでsecretキーが返されます。メソッドがfalseを返す場合、secretキーは、クライアントに送信される前にリソースレスポンスから削除されます。whenメソッドを使用すると、配列を作成するときに条件文に頼ることなく、リソースを表現的に定義できます。In this example, the secret key will only be returned in the final resource response if the authenticated user's isAdmin method returns true. If the method returns false, the secret key will be removed from the resource response before it is sent to the client. The when method allows you to expressively define your resources without resorting to conditional statements when building the array.

whenメソッドは2番目の引数としてクロージャも受け入れ、指定する条件がtrueの場合にのみ結果の値を計算できるようにします。The when method also accepts a closure as its second argument, allowing you to calculate the resulting value only if the given condition is true:

'secret' => $this->when($request->user()->isAdmin(), function () {
    return 'secret-value';
}),

whenHasメソッドは、元となるモデルへ実際にその属性が存在する場合に含めたい時に使えます。The whenHas method may be used to include an attribute if it is actually present on the underlying model:

'name' => $this->whenHas('name'),

さらに、whenNotNullメソッドを使用すると、属性がNULLでない場合、その属性をリソースレスポンスへ含められます。Additionally, the whenNotNull method may be used to include an attribute in the resource response if the attribute is not null:

'name' => $this->whenNotNull($this->name),

条件付き属性のマージMerging Conditional Attributes

同じ条件に基づいてリソースレスポンスにのみ含める必要のある属性が複数存在する場合があります。この場合、指定する条件がtrueの場合にのみ、mergeWhenメソッドを使用して属性をレスポンスへ含められます。Sometimes you may have several attributes that should only be included in the resource response based on the same condition. In this case, you may use the mergeWhen method to include the attributes in the response only when the given condition is true:

/**
 * リソースを配列に変換
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        $this->mergeWhen($request->user()->isAdmin(), [
            'first-secret' => 'value',
            'second-secret' => 'value',
        ]),
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

この場合も、指定する条件がfalseの場合、これらの属性は、クライアントに送信される前にリソースレスポンスから削除されます。Again, if the given condition is false, these attributes will be removed from the resource response before it is sent to the client.

warning Warning! mergeWhenメソッドは、文字列キーと数値キーが混在する配列内では使用しないでください。さらに、順番に並べられていない数値キーを持つ配列内では使用しないでください。Warning
The mergeWhen method should not be used within arrays that mix string and numeric keys. Furthermore, it should not be used within arrays with numeric keys that are not ordered sequentially.

条件付きリレーションConditional Relationships

条件付きで属性をロードすることに加え、リレーションがすでにモデルにロードされているかどうかの条件付きで、リソースレスポンスへリレーションを含めることもできます。これにより、コントローラはモデルにロードする必要のあるリレーションを決定でき、リソースは実際にロードされた場合にのみ簡単に含めることができます。最終的に、これにより、リソース内の「N+1」クエリの問題を簡単に回避できます。In addition to conditionally loading attributes, you may conditionally include relationships on your resource responses based on if the relationship has already been loaded on the model. This allows your controller to decide which relationships should be loaded on the model and your resource can easily include them only when they have actually been loaded. Ultimately, this makes it easier to avoid "N+1" query problems within your resources.

whenLoadedメソッドを使用して、リレーションを条件付きでロードできます。リレーションを不必要にロードすることを避けるために、このメソッドはリレーション自体ではなくリレーション名を引数に取ります。The whenLoaded method may be used to conditionally load a relationship. In order to avoid unnecessarily loading relationships, this method accepts the name of the relationship instead of the relationship itself:

use App\Http\Resources\PostResource;

/**
 * リソースを配列に変換
 *
 * @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,
    ];
}

この例では、リレーションがロードされていない場合、postsキーはクライアントに送信される前に、リソースレスポンスから削除されます。In this example, if the relationship has not been loaded, the posts key will be removed from the resource response before it is sent to the client.

条件付きリレーションカウントConditional Relationship Counts

条件付きでリレーションを含めることに加えて、リレーションのカウントがモデルにロード済みかどうかにもとづき、リソースレスポンスへリレーションの「カウント(count)」を条件付きで含められます。In addition to conditionally including relationships, you may conditionally include relationship "counts" on your resource responses based on if the relationship's count has been loaded on the model:

new UserResource($user->loadCount('posts'));

whenCountedメソッドを使用すると、リレーションシップのカウントを条件付きでリソースレスポンスに含めることができます。このメソッドは、リレーションシップのカウントが存在しない場合に、不必要に属性をインクルードする事態を避けます。The whenCounted method may be used to conditionally include a relationship's count in your resource response. This method avoids unnecessarily including the attribute if the relationships' count is not present:

/**
 * リソースを配列へ変換する
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'posts_count' => $this->whenCounted('posts'),
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

この例では、postsリレーションのカウントがロードされていない場合、posts_countキーはクライアントへ送信される前に、リソースレスポンスから削除されます。In this example, if the posts relationship's count has not been loaded, the posts_count key will be removed from the resource response before it is sent to the client.

条件付きピボット情報Conditional Pivot Information

リソースレスポンスへリレーション情報を条件付きで含めることに加えて、whenPivotLoadedメソッドを使用して、多対多関係の中間テーブルからのデータを条件付きで含めることもできます。whenPivotLoadedメソッドは、最初の引数にピボットテーブル名を取ります。2番目の引数は、モデルでピボット情報が利用可能な場合に返す値を返すクロージャである必要があります。In addition to conditionally including relationship information in your resource responses, you may conditionally include data from the intermediate tables of many-to-many relationships using the whenPivotLoaded method. The whenPivotLoaded method accepts the name of the pivot table as its first argument. The second argument should be a closure that returns the value to be returned if the pivot information is available on the model:

/**
 * リソースを配列に変換
 *
 * @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;
        }),
    ];
}

リレーションがカスタム中間テーブルモデルを使用している場合は、whenPivotLoadedメソッドへの最初の引数に中間テーブルモデルのインスタンスを渡すことができます。:If your relationship is using a custom intermediate table model[/docs/{{version}}/eloquent-relationships#defining-custom-intermediate-table-models], you may pass an instance of the intermediate table model as the first argument to the whenPivotLoaded method:

'expires_at' => $this->whenPivotLoaded(new Membership, function () {
    return $this->pivot->expires_at;
}),

中間テーブルがpivot以外のアクセサを使用している場合は、whenPivotLoadedAsメソッドを使用します。If your intermediate table is using an accessor other than pivot, you may use the whenPivotLoadedAs method:

/**
 * リソースを配列に変換
 *
 * @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;
        }),
    ];
}

メタデータの追加Adding Meta Data

一部のJSON API基準では、リソースおよびリソースコレクションのレスポンスへメタデータを追加する必要があります。これには多くの場合、リソースまたは関連リソースへの「リンク(links)」や、リソース自体に関するメタデータなどが含まれます。リソースに関する追加のメタデータを返す必要がある場合は、それをtoArrayメソッドに含めます。たとえば、リソースコレクションを変換するときにlink情報を含めることができます。Some JSON API standards require the addition of meta data to your resource and resource collections responses. This often includes things like links to the resource or related resources, or meta data about the resource itself. If you need to return additional meta data about a resource, include it in your toArray method. For example, you might include link information when transforming a resource collection:

/**
 * リソースを配列に変換
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
    return [
        'data' => $this->collection,
        'links' => [
            'self' => 'link-value',
        ],
    ];
}

リソースから追​​加のメタデータを返す場合、ページ付けされたレスポンスを返すときにLaravelによって自動的に追加されるlinksまたはmetaキーを誤ってオーバーライドしてしまうことを心配する必要はありません。追加定義したlinksは、ページネーターによって提供されるリンクとマージされます。When returning additional meta data from your resources, you never have to worry about accidentally overriding the links or meta keys that are automatically added by Laravel when returning paginated responses. Any additional links you define will be merged with the links provided by the paginator.

トップレベルのメタデータTop Level Meta Data

リソースが返えす最も外側のリソースである場合、リソースレスポンスへ特定のメタデータのみを含めたい場合があります。通常、これにはレスポンス全体に関するメタ情報が含まれます。このメタデータを定義するには、リソースクラスにwithメソッドを追加します。このメソッドは、リソースが変換される最も外側のリソースである場合にのみ、リソースレスポンスに含めるメタデータの配列を返す必要があります。Sometimes you may wish to only include certain meta data with a resource response if the resource is the outermost resource being returned. Typically, this includes meta information about the response as a whole. To define this meta data, add a with method to your resource class. This method should return an array of meta data to be included with the resource response only when the resource is the outermost resource being transformed:

<?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);
    }

    /**
     * Getリソース配列とともに返す必要のある追加データ
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function with($request)
    {
        return [
            'meta' => [
                'key' => 'value',
            ],
        ];
    }
}

リソースを構築する際のメタデータの追加Adding Meta Data When Constructing Resources

ルートまたはコントローラでリソースインスタンスを構築するときに、トップレベルのデータを追加することもできます。すべてのリソースで使用できるadditionalメソッドは、リソースレスポンスへ追加する必要のあるデータの配列を引数に取ります。You may also add top-level data when constructing resource instances in your route or controller. The additional method, which is available on all resources, accepts an array of data that should be added to the resource response:

return (new UserCollection(User::all()->load('roles')))
                ->additional(['meta' => [
                    'key' => 'value',
                ]]);

リソースレスポンスResource Responses

すでにお読みになったように、リソースはルートとコントローラから直接返します。As you have already read, resources may be returned directly from routes and controllers:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/user/{id}', function ($id) {
    return new UserResource(User::findOrFail($id));
});

しかし、クライアントに送信する前に、送信HTTPレスポンスをカスタマイズする必要が起きる場合があります。これを実現するには2つの方法があります。最初の方法は、responseメソッドをリソースにチェーンすることです。このメソッドはIlluminate\Http\JsonResponseインスタンスを返し、皆さんがレスポンスのヘッダを完全にコントロールできるようにします。However, sometimes you may need to customize the outgoing HTTP response before it is sent to the client. There are two ways to accomplish this. First, you may chain the response method onto the resource. This method will return an Illuminate\Http\JsonResponse instance, giving you full control over the response's headers:

use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/user', function () {
    return (new UserResource(User::find(1)))
                ->response()
                ->header('X-Value', 'True');
});

もう一つの方法は、リソース自身の中でwithResponseメソッドを定義することです。このメソッドは、リソースがレスポンスにおいて最も外側のリソースとして返されるときに呼び出されます。Alternatively, you may define a withResponse method within the resource itself. This method will be called when the resource is returned as the outermost resource in a response:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * リソースを配列に変換
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
        ];
    }

    /**
     * リソースの送信レスポンスのカスタマイズ
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Http\Response  $response
     * @return void
     */
    public function withResponse($request, $response)
    {
        $response->header('X-Value', 'True');
    }
}

章選択

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作