Skip to main content

Используем Api Resource в Laravel

С выходом Laravel 5.5 пришло множество интересных изменений, одно из которых Api ресурсы. Этот ресурс помогает преобразовать вашу модель или коллекцию в красивый JSON ответ. Ранее мы игрались с $hidden/$visible атрибутами и это был сущий ад. В этой статье мы рассмотрим пару интересных примеров использования Api Resources.

Создание ресурсов

Первым делом ресурс нужно создать, делается это командой:

php artisan make:resource UserResource

После выполнения команды будет создан файл UserResource в папке app/Http/Resources. Также все классы ресурсов наследуются от Illuminate\Http\Resources\Json\Resource, потому вы можете вручную создавать свои ресурсы.

Таким образом мы создали коллекцию для модели User. Однако если мы хотим передавать в JSON ответе много объектов пользователей, нам нужно создать коллекцию. Создание коллекции делается такой же коммандой но с добавлением параметра --collection или вконце имени ресурса добавить слово Collection

php artisan make:resource Users --collection

php artisan make:resource UserCollection

Файл будет создан в той же папке, что и описывалось выше, но класс будет унаследован от Illuminate\Http\Resources\Json\ResourceCollection

Новый класс будет выглядеть примерно следующим образом:

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class UserResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\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.

Для вывода ответа ранее мы использовали примерно такой код:

return response()->json(['data' => $users]);

Сейчас же все намного проще:

return new UserResource($user);

Или отдать коллекцию:

return UserResource::collection(User::all);

Коллекция же отличается совсем не много:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}

Под коллекцию необязательно создавать отдельный класс, но если вы хотите добавить к ответу какие-то данные, например ссылки как в примере выше, то нужно сделать отдельный класс.

Отношения моделей

Также в коллекции мы можем передавать и отношения модели, если таковы имеются. Простенький пример ниже вам всё объяснит:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'posts' => Post::collection($this->posts),
        'created_at' => $this->created_at,
        'updated_at' => $this->updated_at,
    ];
}

Ресурс PostResource должен быть создан и отредактирован.

Пагинация

Как мы знаем, laravel предоставляет постраничную навигацию и её мы можем применить к ресурсным коллекциям. Вот так мы возвращаем результат:

return new UserCollection(User::paginate());

А ответ получаем вот такой:

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

Думаю, разобраться в этом сложностей не составит.
Вся информация взята с официального источника.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *