Skip to main content

APIリソースとは

APIを構築するとき、EloquentモデルをそのままJSONとして返すと、隠したいカラムが漏れたり、クライアントが必要としていない大量のデータを送り付けてしまうことがあります。 Eloquent APIリソースは、モデルとJSONレスポンスの間に変換レイヤーを挟む仕組みです。toArray() メソッドで「何をどの形式でレスポンスに含めるか」を明示的に定義できます。 主なメリットは次のとおりです。
  • レスポンスに含めるフィールドを完全にコントロールできる
  • フィールド名の変換や値の加工をひとつの場所にまとめられる
  • 条件によってフィールドを出し分けられる
  • リレーションをネストして一貫した構造を保てる

リソースの作成

make:resource Artisanコマンドでリソースクラスを生成します。
生成されたクラスは app/Http/Resources ディレクトリに置かれます。
$this でモデルのプロパティに直接アクセスできます。これはリソースクラスが内部でモデルへのアクセスをプロキシしているためです。

コントローラーでの使用

定義したリソースはコントローラーやルートから返せます。
または、モデルの toResource() メソッドを使う方法もあります。
toResource() はモデル名に基づいて対応するリソースクラス(UserResource)を自動的に探します。 デフォルトでは、レスポンスは data キーでラップされます。

リソースコレクション

複数のモデルを返す場合は collection() メソッドを使います。
または、Eloquentコレクションの toResourceCollection() を使います。

カスタムコレクションリソース

コレクション全体にメタデータを付加したい場合は、専用のコレクションリソースを作成します。

フィールドの加工と変換

toArray() 内でフィールド名の変更や値の加工ができます。

条件付きフィールド

when() — 条件に応じてフィールドを追加

特定の条件を満たすときだけフィールドを含めたい場合は when() を使います。
when() の条件が false のとき、そのキー自体がレスポンスから取り除かれます。

mergeWhen() — 複数フィールドをまとめて条件付き追加

同じ条件で複数のフィールドをまとめて出し分けるには mergeWhen() を使います。

whenLoaded() — ロード済みリレーションのみ含める

リレーションがEagerロードされているときだけ含めることで、N+1問題を防ぎながら柔軟なレスポンスを作れます。
コントローラー側でリレーションをロードするかどうかを制御できます。

whenCounted() — カウントを条件付きで含める

loadCount() で取得したリレーションのカウントを条件付きで含めます。

ネストしたリソース

リレーションを別のリソースクラスでネストすることで、一貫した構造を保てます。

メタデータの追加

with() — トップレベルのメタデータ

コレクション全体にメタデータを付加するには with() メソッドをオーバーライドします。
レスポンス例:

additional() — 動的にメタデータを追加

コントローラー側で動的にメタデータを追加したい場合は additional() を使います。

ページネーションとの組み合わせ

ページネーション結果をリソースに渡すだけで、metalinks が自動的に付加されます。
または:
レスポンス例:
ページネーションレスポンスでは、withoutWrapping() を呼んでいても data キーは必ず付きます。ページネーションの metalinks キーと共存させるためです。

データラッピングの無効化

デフォルトでは最外層のリソースが data キーにラップされます。これを無効にするには AppServiceProviderboot() 内で withoutWrapping() を呼びます。
withoutWrapping() は最外層のラッピングのみに影響します。自分で定義した data キーは削除されません。

実践例:ユーザーAPIの実装

ユーザー管理APIを例に、リソースを使った一貫したレスポンス設計を示します。

UserResource

UserController

関連ページ

Eloquentリレーション入門

リレーションの定義方法とEagerローディングを確認します。

ページネーション

ページネーション結果をAPIリソースと組み合わせる方法を確認します。
最終更新日 2026年4月3日