<? phpukraine ДОКУМЕНТАЦІЯ
Пошук по платформі
Документація українською

Переклад офіційної документації українською. Кожен розділ показує стан готовності: недоперекладене позначене відкрито, а не приховане.

ВЕРСІЯ
АКТУАЛЬНА Актуальний реліз. Переклад наздоганяє оригінал, розділи з низьким відсотком позначені у змісті.
ELOQUENT · ПЕРЕКЛАДЕНО оновлено 15 вересня 2026

API-ресурси · Laravel

Коли ви будуєте API, вам може знадобитися шар перетворення, який стоїть між вашими Eloquent-моделями і JSON-відповідями, що реально повертаються користувачам застосунку. Наприклад, ви можете захотіти показувати певні атрибути лише частині користувачів, або завжди включати певні звʼязки в JSON-представлення ваших моделей. Класи ресурсів Eloquent дозволяють виразно й легко перетворювати моделі та колекції моделей у JSON.

Звісно, ви завжди можете перетворити Eloquent-моделі чи колекції в JSON методом toJson; проте ресурси Eloquent дають детальніший і надійніший контроль над JSON-серіалізацією моделей та їхніх звʼязків.

Генерація ресурсів

Щоб згенерувати клас ресурсу, скористайтеся Artisan-командою make:resource. За замовчуванням ресурси розміщуються в теці app/Http/Resources вашого застосунку. Ресурси розширюють клас Illuminate\Http\Resources\Json\JsonResource:

php artisan make:resource UserResource

Колекції ресурсів

Крім ресурсів, які перетворюють окремі моделі, ви можете генерувати ресурси, що відповідають за перетворення колекцій моделей. Це дозволяє вашим JSON-відповідям містити посилання та іншу мета-інформацію, доречну для цілої колекції певного ресурсу.

Щоб створити колекцію ресурсів, використовуйте прапорець --collection під час створення ресурсу. Або ж слово Collection в імені ресурсу підкаже Laravel, що треба створити ресурс-колекцію. Ресурси-колекції розширюють клас Illuminate\Http\Resources\Json\ResourceCollection:

php artisan make:resource User --collection

php artisan make:resource UserCollection

Огляд концепції

[!NOTE] Це огляд ресурсів і колекцій ресурсів з висоти пташиного польоту. Наполегливо радимо прочитати інші розділи цієї документації, щоб глибше зрозуміти можливості налаштування й силу, які дають ресурси.

Перш ніж занурюватися в усі доступні опції написання ресурсів, погляньмо загально на те, як ресурси використовуються в Laravel. Клас ресурсу представляє одну модель, яку треба перетворити на JSON-структуру. Ось, наприклад, простий клас ресурсу UserResource:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Перетворити ресурс на масив.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

Кожен клас ресурсу визначає метод toArray, який повертає масив атрибутів, що мають бути перетворені на JSON, коли ресурс повертається як відповідь із маршруту чи методу контролера.

Зверніть увагу, що властивості моделі доступні напряму через змінну $this. Так відбувається тому, що клас ресурсу автоматично проксіює звернення до властивостей і методів до моделі, яка лежить в основі, для зручного доступу. Щойно ресурс визначено, його можна повернути з маршруту чи контролера. Ресурс приймає екземпляр моделі через свій конструктор:

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

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

Для зручності ви можете скористатися методом моделі toResource, який за конвенціями фреймворку автоматично знайде відповідний ресурс моделі:

return User::findOrFail($id)->toResource();

Під час виклику методу toResource Laravel спробує знайти ресурс, імʼя якого збігається з імʼям моделі і, можливо, має суфікс Resource, у просторі імен Http\Resources, найближчому до простору імен моделі.

Якщо ваш клас ресурсу не дотримується цієї конвенції іменування або лежить в іншому просторі імен, ви можете вказати ресурс за замовчуванням для моделі через атрибут UseResource:

<?php

namespace App\Models;

use App\Http\Resources\CustomUserResource;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Attributes\UseResource;

#[UseResource(CustomUserResource::class)]
class User extends Model
{
    // ...
}

Або ж ви можете вказати клас ресурсу, передавши його в метод toResource:

return User::findOrFail($id)->toResource(CustomUserResource::class);

Колекції ресурсів

Якщо ви повертаєте колекцію ресурсів або відповідь із пагінацією, використовуйте метод collection, який надає ваш клас ресурсу, під час створення екземпляра ресурсу в маршруті чи контролері:

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

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

Або, для зручності, скористайтеся методом Eloquent-колекції toResourceCollection, який за конвенціями фреймворку автоматично знайде відповідну колекцію ресурсів для моделі:

return User::all()->toResourceCollection();

Під час виклику методу toResourceCollection Laravel спробує знайти колекцію ресурсів, імʼя якої збігається з імʼям моделі та має суфікс Collection, у просторі імен Http\Resources, найближчому до простору імен моделі.

Якщо ваш клас колекції ресурсів не дотримується цієї конвенції іменування або лежить в іншому просторі імен, ви можете вказати колекцію ресурсів за замовчуванням для моделі через атрибут UseResourceCollection:

<?php

namespace App\Models;

use App\Http\Resources\CustomUserCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Attributes\UseResourceCollection;

#[UseResourceCollection(CustomUserCollection::class)]
class User extends Model
{
    // ...
}

Або ж ви можете вказати клас колекції ресурсів, передавши його в метод toResourceCollection:

return User::all()->toResourceCollection(CustomUserCollection::class);

Власні колекції ресурсів

За замовчуванням колекції ресурсів не дозволяють додавати власні мета-дані, які може знадобитися повернути разом із колекцією. Якщо ви хочете налаштувати відповідь колекції ресурсів, створіть окремий ресурс, що представлятиме цю колекцію:

php artisan make:resource UserCollection

Після генерації класу колекції ресурсів ви легко визначите будь-які мета-дані, які треба включити у відповідь:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Перетворити колекцію ресурсів на масив.
     *
     * @return array<int|string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}

Після визначення колекції ресурсів її можна повернути з маршруту чи контролера:

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

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

Або, для зручності, скористайтеся методом Eloquent-колекції toResourceCollection, який за конвенціями фреймворку автоматично знайде відповідну колекцію ресурсів для моделі:

return User::all()->toResourceCollection();

Під час виклику методу toResourceCollection Laravel спробує знайти колекцію ресурсів, імʼя якої збігається з імʼям моделі та має суфікс Collection, у просторі імен Http\Resources, найближчому до простору імен моделі.

Збереження ключів колекції

Коли з маршруту повертається колекція ресурсів, Laravel скидає ключі колекції так, щоб вони йшли в числовому порядку. Проте ви можете застосувати атрибут PreserveKeys до класу ресурсу, вказавши, що оригінальні ключі колекції треба зберегти:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Attributes\PreserveKeys;
use Illuminate\Http\Resources\Json\JsonResource;

#[PreserveKeys]
class UserResource extends JsonResource
{
    // ...
}

Коли властивість preserveKeys має значення true, ключі колекції зберігаються при поверненні колекції з маршруту чи контролера:

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

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

Налаштування базового класу ресурсу

Зазвичай властивість $this->collection колекції ресурсів автоматично заповнюється результатом відображення кожного елемента колекції на його одиничний клас ресурсу. Одиничним класом ресурсу вважається імʼя класу колекції без кінцевої частини Collection. Крім того, залежно від ваших уподобань, одиничний клас ресурсу може мати або не мати суфікс Resource.

Наприклад, UserCollection спробує відобразити передані екземпляри користувачів на ресурс UserResource. Щоб змінити цю поведінку, застосуйте атрибут Collects до вашої колекції ресурсів:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Attributes\Collects;
use Illuminate\Http\Resources\Json\ResourceCollection;

#[Collects(Member::class)]
class UserCollection extends ResourceCollection
{
    // ...
}

Написання ресурсів

[!NOTE] Якщо ви ще не читали огляд концепції, радимо зробити це перед тим, як продовжувати цю документацію.

Ресурсам потрібно лише перетворити задану модель на масив. Тож кожен ресурс містить метод toArray, який переводить атрибути моделі в зручний для API масив, що його можна повернути з маршрутів чи контролерів вашого застосунку:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Перетворити ресурс на масив.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];
    }
}

Щойно ресурс визначено, його можна повернути прямо з маршруту чи контролера:

use App\Models\User;

Route::get('/user/{id}', function (string $id) {
    return User::findOrFail($id)->toUserResource();
});

Звʼязки

Якщо ви хочете включити повʼязані ресурси у відповідь, додайте їх до масиву, який повертає метод toArray вашого ресурсу. У цьому прикладі ми скористаємося методом collection ресурсу PostResource, щоб додати пости блогу користувача до відповіді ресурсу:

use App\Http\Resources\PostResource;
use Illuminate\Http\Request;

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    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,
    ];
}

[!NOTE] Якщо ви хочете включати звʼязки лише тоді, коли їх уже завантажено, перегляньте документацію про умовні звʼязки.

Колекції ресурсів

Ресурси перетворюють одну модель на масив, а колекції ресурсів перетворюють на масив колекцію моделей. Проте визначати клас колекції ресурсів для кожної моделі геть не обовʼязково, оскільки всі колекції Eloquent-моделей мають метод toResourceCollection, який на льоту створює «ad-hoc» колекцію ресурсів:

use App\Models\User;

Route::get('/users', function () {
    return User::all()->toResourceCollection();
});

Але якщо вам потрібно налаштувати мета-дані, що повертаються з колекцією, доведеться визначити власну колекцію ресурсів:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Перетворити колекцію ресурсів на масив.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}

Як і одиничні ресурси, колекції ресурсів можна повертати прямо з маршрутів чи контролерів:

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

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

Або, для зручності, скористайтеся методом Eloquent-колекції toResourceCollection, який за конвенціями фреймворку автоматично знайде відповідну колекцію ресурсів для моделі:

return User::all()->toResourceCollection();

Під час виклику методу toResourceCollection Laravel спробує знайти колекцію ресурсів, імʼя якої збігається з імʼям моделі та має суфікс Collection, у просторі імен Http\Resources, найближчому до простору імен моделі.

Обгортання даних

За замовчуванням найзовнішній ресурс обгортається в ключ data, коли відповідь ресурсу перетворюється на JSON. Наприклад, типова відповідь колекції ресурсів виглядає так:

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

Якщо ви хочете вимкнути обгортання найзовнішнього ресурсу, викличте метод withoutWrapping на базовому класі Illuminate\Http\Resources\Json\JsonResource. Зазвичай цей метод викликають із AppServiceProvider або іншого сервіс-провайдера, що завантажується на кожен запит до застосунку:

<?php

namespace App\Providers;

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

class AppServiceProvider extends ServiceProvider
{
    /**
     * Зареєструвати будь-які сервіси застосунку.
     */
    public function register(): void
    {
        // ...
    }

    /**
     * Завантажити будь-які сервіси застосунку.
     */
    public function boot(): void
    {
        JsonResource::withoutWrapping();
    }
}

[!WARNING] Метод withoutWrapping впливає лише на найзовнішню відповідь і не прибирає ключі data, які ви вручну додали у власні колекції ресурсів.

Обгортання вкладених ресурсів

Ви маєте повну свободу у виборі того, як обгортаються звʼязки вашого ресурсу. Якщо ви хочете, щоб усі колекції ресурсів обгорталися в ключ data незалежно від рівня вкладеності, визначте клас колекції ресурсів для кожного ресурсу і повертайте колекцію всередині ключа data.

Можливо, вам цікаво, чи не призведе це до подвійного обгортання найзовнішнього ресурсу в два ключі data. Не хвилюйтеся: Laravel ніколи не дозволить випадково обгорнути ресурси двічі, тож вам не треба перейматися рівнем вкладеності колекції ресурсів, яку ви перетворюєте:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class CommentsCollection extends ResourceCollection
{
    /**
     * Перетворити колекцію ресурсів на масив.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return ['data' => $this->collection];
    }
}

Обгортання даних і пагінація

Коли ви повертаєте колекції з пагінацією через відповідь ресурсу, Laravel обгорне дані ресурсу в ключ data, навіть якщо було викликано метод withoutWrapping. Так відбувається тому, що відповіді з пагінацією завжди містять ключі meta і links з інформацією про стан пагінатора:

{
    "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/users?page=1",
        "last": "http://example.com/users?page=1",
        "prev": null,
        "next": null
    },
    "meta":{
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "http://example.com/users",
        "per_page": 15,
        "to": 10,
        "total": 10
    }
}

Пагінація

Ви можете передати екземпляр пагінатора Laravel у метод collection ресурсу або у власну колекцію ресурсів:

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

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

Або, для зручності, скористайтеся методом пагінатора toResourceCollection, який за конвенціями фреймворку автоматично знайде відповідну колекцію ресурсів для моделі з пагінацією:

return User::paginate()->toResourceCollection();

Відповіді з пагінацією завжди містять ключі meta і links з інформацією про стан пагінатора:

{
    "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/users?page=1",
        "last": "http://example.com/users?page=1",
        "prev": null,
        "next": null
    },
    "meta":{
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "http://example.com/users",
        "per_page": 15,
        "to": 10,
        "total": 10
    }
}

Налаштування інформації про пагінацію

Якщо ви хочете змінити інформацію, що входить у ключі links чи meta відповіді з пагінацією, визначте на ресурсі метод paginationInformation. Цей метод отримає дані $paginated і масив інформації $default, який містить ключі links і meta:

/**
 * Налаштувати інформацію про пагінацію для ресурсу.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  array  $paginated
 * @param  array  $default
 * @return array
 */
public function paginationInformation($request, $paginated, $default)
{
    $default['links']['custom'] = 'https://example.com';

    return $default;
}

Умовні атрибути

Іноді потрібно включати атрибут у відповідь ресурсу лише за виконання певної умови. Наприклад, ви можете хотіти віддавати значення лише тоді, коли поточний користувач - «адміністратор». Laravel дає для цього кілька допоміжних методів. Метод when дозволяє умовно додати атрибут до відповіді ресурсу:

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    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,
    ];
}

У цьому прикладі ключ secret потрапить у підсумкову відповідь ресурсу лише тоді, коли метод isAdmin автентифікованого користувача повертає true. Якщо метод повертає false, ключ secret буде прибрано з відповіді ресурсу перед відправленням клієнту. Метод when дозволяє виразно описувати ресурси, не вдаючись до умовних конструкцій під час побудови масиву.

Метод when також приймає замикання другим аргументом, тож підсумкове значення обчислюється лише тоді, коли задана умова true:

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

Метод whenHas дозволяє включити атрибут, якщо він справді присутній на моделі:

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

Крім того, метод whenNotNull включає атрибут у відповідь ресурсу, якщо атрибут не дорівнює null:

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

Обʼєднання умовних атрибутів

Іноді у вас є кілька атрибутів, які треба включати у відповідь ресурсу за однією й тією самою умовою. У такому разі скористайтеся методом mergeWhen, щоб включити атрибути у відповідь лише тоді, коли задана умова true:

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    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, ці атрибути буде прибрано з відповіді ресурсу перед відправленням клієнту.

[!WARNING] Метод mergeWhen не слід використовувати всередині масивів, де змішані рядкові й числові ключі. Крім того, його не слід використовувати всередині масивів із числовими ключами, що йдуть не послідовно.

Умовні звʼязки

Крім умовного завантаження атрибутів, ви можете умовно включати звʼязки у відповіді ресурсу залежно від того, чи звʼязок уже завантажено на моделі. Це дозволяє контролеру вирішувати, які звʼязки треба завантажити на моделі, а ресурс легко включить їх лише тоді, коли їх справді завантажено. Зрештою, так простіше уникати проблем із запитами «N+1» усередині ресурсів.

Метод whenLoaded дозволяє умовно завантажити звʼязок. Щоб уникнути зайвого завантаження звʼязків, цей метод приймає імʼя звʼязку, а не сам звʼязок:

use App\Http\Resources\PostResource;

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    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 буде прибрано з відповіді ресурсу перед відправленням клієнту.

Умовні підрахунки звʼязків

Крім умовного включення звʼязків, ви можете умовно включати «підрахунки» звʼязків у відповіді ресурсу залежно від того, чи підрахунок звʼязку завантажено на моделі:

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

Метод whenCounted дозволяє умовно включити підрахунок звʼязку у відповідь ресурсу. Цей метод не додає атрибут зайвий раз, якщо підрахунок звʼязку відсутній:

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    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 буде прибрано з відповіді ресурсу перед відправленням клієнту.

Інші типи агрегатів, як-от avg, sum, min і max, теж можна умовно завантажувати методом whenAggregated:

'words_avg' => $this->whenAggregated('posts', 'words', 'avg'),
'words_sum' => $this->whenAggregated('posts', 'words', 'sum'),
'words_min' => $this->whenAggregated('posts', 'words', 'min'),
'words_max' => $this->whenAggregated('posts', 'words', 'max'),

Умовна інформація з проміжної таблиці

Крім умовного включення інформації про звʼязки у відповіді ресурсу, ви можете умовно включати дані з проміжних таблиць звʼязків «багато до багатьох» за допомогою методу whenPivotLoaded. Метод whenPivotLoaded першим аргументом приймає імʼя проміжної таблиці. Другим аргументом має бути замикання, яке повертає значення, що віддається, якщо інформація з проміжної таблиці доступна на моделі:

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'expires_at' => $this->whenPivotLoaded('role_user', function () {
            return $this->pivot->expires_at;
        }),
    ];
}

Якщо ваш звʼязок використовує власну модель проміжної таблиці, ви можете передати екземпляр моделі проміжної таблиці першим аргументом у метод whenPivotLoaded:

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

Якщо ваша проміжна таблиця використовує аксесор, відмінний від pivot, скористайтеся методом whenPivotLoadedAs:

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'expires_at' => $this->whenPivotLoadedAs('subscription', 'role_user', function () {
            return $this->subscription->expires_at;
        }),
    ];
}

Додавання мета-даних

Деякі стандарти JSON API вимагають додавати мета-дані до відповідей ресурсів і колекцій ресурсів. Часто це links на ресурс чи повʼязані ресурси, або мета-дані про сам ресурс. Якщо вам треба повернути додаткові мета-дані про ресурс, включіть їх у метод toArray. Наприклад, ви можете включити інформацію links під час перетворення колекції ресурсів:

/**
 * Перетворити ресурс на масив.
 *
 * @return array<string, mixed>
 */
public function toArray(Request $request): array
{
    return [
        'data' => $this->collection,
        'links' => [
            'self' => 'link-value',
        ],
    ];
}

Повертаючи додаткові мета-дані з ресурсів, вам не треба хвилюватися про випадкове перезаписування ключів links чи meta, які Laravel автоматично додає у відповіді з пагінацією. Будь-які додаткові links, які ви визначите, буде обʼєднано з посиланнями від пагінатора.

Мета-дані верхнього рівня

Іноді ви можете хотіти включати певні мета-дані у відповідь ресурсу лише тоді, коли цей ресурс - найзовнішній із тих, що повертаються. Зазвичай це мета-інформація про відповідь загалом. Щоб визначити такі мета-дані, додайте метод with до класу ресурсу. Цей метод має повертати масив мета-даних, що включаються у відповідь ресурсу лише тоді, коли ресурс є найзовнішнім із тих, що перетворюються:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Перетворити колекцію ресурсів на масив.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return parent::toArray($request);
    }

    /**
     * Отримати додаткові дані, які треба повернути разом із масивом ресурсу.
     *
     * @return array<string, mixed>
     */
    public function with(Request $request): array
    {
        return [
            'meta' => [
                'key' => 'value',
            ],
        ];
    }
}

Додавання мета-даних під час створення ресурсів

Ви також можете додати дані верхнього рівня під час створення екземплярів ресурсу в маршруті чи контролері. Метод additional, доступний на всіх ресурсах, приймає масив даних, які треба додати до відповіді ресурсу:

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

Ресурси JSON:API

Laravel постачається з JsonApiResource - класом ресурсу, який видає відповіді, сумісні зі специфікацією JSON:API. Він розширює стандартний клас JsonResource і автоматично опрацьовує структуру обʼєкта ресурсу, звʼязки, sparse fieldsets, включення (includes), ліниве обчислення атрибутів, а також ставить заголовок Content-Type у значення application/vnd.api+json.

[!NOTE] Ресурси JSON:API в Laravel відповідають за серіалізацію ваших відповідей. Якщо вам також треба розбирати вхідні query-параметри JSON:API, як-от фільтри й сортування, чудовим доповненням буде пакет Spatie's Laravel Query Builder.

Генерація ресурсів JSON:API

Щоб згенерувати ресурс JSON:API, скористайтеся Artisan-командою make:resource із прапорцем --json-api:

php artisan make:resource PostResource --json-api

Згенерований клас розширить Illuminate\Http\Resources\JsonApi\JsonApiResource і міститиме властивості $attributes та $relationships, які вам треба заповнити:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\JsonApi\JsonApiResource;

class PostResource extends JsonApiResource
{
    /**
     * Атрибути ресурсу.
     */
    public $attributes = [
        // ...
    ];

    /**
     * Звʼязки ресурсу.
     */
    public $relationships = [
        // ...
    ];
}

Ресурси JSON:API можна повертати з маршрутів і контролерів так само, як звичайні ресурси:

use App\Http\Resources\PostResource;
use App\Models\Post;

Route::get('/api/posts/{post}', function (Post $post) {
    return new PostResource($post);
});

Або, для зручності, скористайтеся методом моделі toResource:

Route::get('/api/posts/{post}', function (Post $post) {
    return $post->toResource();
});

Це дасть відповідь, сумісну з JSON:API:

{
    "data": {
        "id": "1",
        "type": "posts",
        "attributes": {
            "title": "Hello World",
            "body": "This is my first post."
        }
    }
}

Щоб повернути колекцію ресурсів JSON:API, використовуйте метод collection або зручний метод toResourceCollection:

return PostResource::collection(Post::all());

return Post::all()->toResourceCollection();

Визначення атрибутів

Є два способи визначити, які атрибути входять до вашого ресурсу JSON:API.

Найпростіший підхід - оголосити властивість $attributes на ресурсі. Ви можете перелічити імена атрибутів як значення, і їх буде прочитано напряму з моделі:

public $attributes = [
    'title',
    'body',
    'created_at',
];

Якщо обчислення атрибута дороге, поверніть його з toAttributes як замикання, щоб воно обчислювалося лише тоді, коли атрибут справді потрібен у відповіді.

Або, щоб повністю контролювати атрибути ресурсу, перевизначте метод toAttributes на ресурсі:

/**
 * Отримати атрибути ресурсу.
 *
 * @return array<string, mixed>
 */
public function toAttributes(Request $request): array
{
    return [
        'title' => $this->title,
        'body' => $this->body,
        'is_published' => fn () => $this->published_at !== null,
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

Визначення звʼязків

Ресурси JSON:API підтримують визначення звʼязків згідно зі специфікацією JSON:API. Звʼязки серіалізуються лише тоді, коли клієнт запитує їх через query-параметр include.

Властивість $relationships

Ви можете визначити звʼязки ресурсу, доступні для включення, через властивість $relationships:

public $relationships = [
    'author',
    'comments',
];

Коли імʼя звʼязку вказане як значення, Laravel знайде відповідний Eloquent-звʼязок і автоматично визначить потрібний клас ресурсу. Якщо вам треба вказати клас ресурсу явно, оголосіть звʼязок як пару ключ / клас:

use App\Http\Resources\UserResource;

public $relationships = [
    'author' => UserResource::class,
    'comments',
];

Або ж перевизначте метод toRelationships на ресурсі:

/**
 * Отримати звʼязки ресурсу.
 */
public function toRelationships(Request $request): array
{
    return [
        'author' => UserResource::class,
        'comments' => fn () => CommentResource::collection(
            $request->user()->is($this->resource)
                ? $this->comments
                : $this->comments->where('is_public', true),
        ),
    ];
}

Замикання дають більше контролю над вмістом звʼязку, при цьому звʼязок усе одно резолвиться лише тоді, коли клієнт його запитує.

Включення звʼязків

Клієнти можуть запитувати повʼязані ресурси через query-параметр include:

GET /api/posts/1?include=author,comments

Це дає відповідь із обʼєктами-ідентифікаторами ресурсів у ключі relationships і повними обʼєктами ресурсів у масиві included верхнього рівня:

{
    "data": {
        "id": "1",
        "type": "posts",
        "attributes": {
            "title": "Hello World"
        },
        "relationships": {
            "author": {
                "data": {
                    "id": "1",
                    "type": "users"
                }
            },
            "comments": {
                "data": [
                    {
                        "id": "1",
                        "type": "comments"
                    }
                ]
            }
        }
    },
    "included": [
        {
            "id": "1",
            "type": "users",
            "attributes": {
                "name": "Taylor Otwell"
            }
        },
        {
            "id": "1",
            "type": "comments",
            "attributes": {
                "body": "Great post!"
            }
        }
    ]
}

Вкладені звʼязки включаються через крапкову нотацію:

GET /api/posts/1?include=comments.author

Глибина звʼязків

За замовчуванням включення вкладених звʼязків обмежене максимальною глибиною. Ви можете змінити це обмеження методом maxRelationshipDepth, зазвичай в одному із сервіс-провайдерів застосунку:

use Illuminate\Http\Resources\JsonApi\JsonApiResource;

JsonApiResource::maxRelationshipDepth(3);

Тип та ID ресурсу

За замовчуванням type ресурсу виводиться з імені класу ресурсу. Наприклад, PostResource дає тип posts, а BlogPostResource - blog-posts. id ресурсу береться з первинного ключа моделі.

Якщо вам треба змінити ці значення, перевизначте методи toType і toId на вашому ресурсі:

/**
 * Отримати тип ресурсу.
 */
public function toType(Request $request): string
{
    return 'articles';
}

/**
 * Отримати ID ресурсу.
 */
public function toId(Request $request): string
{
    return (string) $this->uuid;
}

Це особливо корисно, коли тип ресурсу має відрізнятися від імені класу: наприклад, AuthorResource обгортає модель User і має віддавати тип authors.

Sparse fieldsets та includes

Ресурси JSON:API підтримують sparse fieldsets, дозволяючи клієнтам запитувати лише певні атрибути для кожного типу ресурсу через query-параметр fields:

GET /api/posts?fields[posts]=title,created_at&fields[users]=name

Так у відповідь потраплять лише атрибути title і created_at для ресурсів posts та атрибут name для ресурсів users.

Ігнорування рядка запиту

Якщо ви хочете вимкнути фільтрацію sparse fieldsets для певної відповіді ресурсу, викличте метод ignoreFieldsAndIncludesInQueryString:

return $post->toResource()
    ->ignoreFieldsAndIncludesInQueryString();

Включення раніше завантажених звʼязків

За замовчуванням звʼязки потрапляють у відповідь лише тоді, коли їх запитано через query-параметр include. Якщо ви хочете включити всі раніше жадібно завантажені звʼязки незалежно від рядка запиту, викличте метод includePreviouslyLoadedRelationships:

return $post->load('author', 'comments')
    ->toResource()
    ->includePreviouslyLoadedRelationships();

Ви можете додати інформацію links і meta до обʼєктів ресурсу JSON:API, перевизначивши методи toLinks і toMeta на ресурсі:

/**
 * Отримати посилання ресурсу.
 */
public function toLinks(Request $request): array
{
    return [
        'self' => route('api.posts.show', $this->resource),
    ];
}

/**
 * Отримати мета-інформацію ресурсу.
 */
public function toMeta(Request $request): array
{
    return [
        'readable_created_at' => $this->created_at->diffForHumans(),
    ];
}

Це додасть ключі links і meta до обʼєкта ресурсу у відповіді:

{
    "data": {
        "id": "1",
        "type": "posts",
        "attributes": {
            "title": "Hello World"
        },
        "links": {
            "self": "https://example.com/api/posts/1"
        },
        "meta": {
            "readable_created_at": "2 hours ago"
        }
    }
}

Відповіді ресурсів

Як ви вже прочитали, ресурси можна повертати прямо з маршрутів і контролерів:

use App\Models\User;

Route::get('/user/{id}', function (string $id) {
    return User::findOrFail($id)->toResource();
});

Проте іноді треба налаштувати вихідну HTTP-відповідь перед тим, як її буде надіслано клієнту. Це можна зробити двома способами. По-перше, ви можете зчепити метод response із ресурсом. Цей метод поверне екземпляр Illuminate\Http\JsonResponse, даючи повний контроль над заголовками відповіді:

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

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

Або ж визначте метод withResponse усередині самого ресурсу. Цей метод буде викликано, коли ресурс повертається як найзовнішній у відповіді:

<?php

namespace App\Http\Resources;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Перетворити ресурс на масив.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
        ];
    }

    /**
     * Налаштувати вихідну відповідь для ресурсу.
     */
    public function withResponse(Request $request, JsonResponse $response): void
    {
        $response->header('X-Value', 'True');
    }
}
ЯК ЦЯ СТОРІНКА ВИГЛЯДАЄ В ПОШУКУ
phpukraine.com/docs/laravel/api-resources
API-ресурси | Документація Laravel українською
API-ресурси у Laravel 13.x: переклад офіційної документації українською. Оновлено 15 вересня 2026. Приклади коду, пояснення та посилання на питання зі співбесід.
Стан перекладу

Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.

90%
Готовності
10
У роботі
0
Ще не перекладено
Глосарій термінів