image

Прошлой ночью Taylor Otwell наконец представил что может стать началом замены Fractal при разработке API на фреймворке Laravel 5.5. Это моя пробная версия статьи, поехали.

Интересный материал начинается с 4-го шага.

1. Установка приложения


composer create-project laravel/laravel responses dev-develop
cd responses
touch database/database.sqlite
php artisan make:model Post -mfa
php artisan make:resource UsersWithPostsResource
php artisan make:resource PostsResource
php artisan make:controller UsersController --resource

Пропишите в файле .env проекта использование базы SQLite, убрав все прочие.

DB_CONNECTION=sqlite

2. Подготовка базы данных


2.1. Создадим миграцию The posts migration

Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title');
    $table->string('body');
    $table->unsignedInteger('user_id');
    $table->timestamps();
});

2.2. Создадим factory: database/factories/PostFactory.php

<?php

use Faker\Generator as Faker;

$factory->define(App\Post::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'body' => $faker->paragraph,
        'user_id' => function () {
            return factory(\App\User::class);
        }
    ];
});

2.3 Добавим отношение в модель app/User.php

public function posts()
{
    return $this->hasMany(Post::class);
}

2.4 Избегайте массового присвоения в сообщениях app/Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $guarded = [];
}

2.5 Заполнение базы тестовыми данными

php artisan migrate:fresh
php artisan tinker
factory(App\Post::class)->times(2)->create();
factory(App\Post::class)->times(2)->create(['user_id' => 1]);

3. Настройка роутов


Route::apiResource('/users', 'UsersController');

4. Преобразование модели в ресурсы


/**
 * Display a listing of the resource.
 *
 * @param User $user
 * @return \Illuminate\Http\Response
 */
public function index(User $user)
{
    return new UsersWithPostsResource($user->paginate());
}

5. Юзеры с ресурсными постами


<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class UsersWithPostsResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        // Eager load
        $this->resource->load('posts');

        return $this->resource->map(function ($item) {
            return [
                'name' => $item->name,
                'email' => $item->email,
                'posts' => new PostsResource($item->posts)
            ];
        });
    }
}

6. Ресурсы постов


<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class PostsResource extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        return $this->resource->map(function ($item) {
            return [
                'title' => $item->title
            ];
        });
    }
}

7. Вывод


Первая явная разница в сравнении с Fractal в том, что ресурс имеет простой и прямой доступ ко всей коллекции, а не к каждому объекту. Это означает, что при преобразовании коллекции пользователей Вы можете легко загружать каждую запись без N+1 запросов.

Вы можете легко трансформировать «точки», так как можете просто создать новый класс ресурсов для преобразования Ваших данных по мере необходимости.

Я хочу более подробно раскрыть эту тему, как только нарою больше возможностей Laravel API Resources.

От переводчика


Посчитал эту тему интересной и решил перевести с адаптацией языка. Прошу ногами не пинать. Также приветствуются линки на оригинальную и переведенную доку по данной тематике.

Комментарии (9)


  1. ange007
    26.08.2017 00:27
    +2

    Балин…
    Вообще ничего не понял. Что/куда и для чего?
    Можно ведь было добавить от переводчика предисловие — что за такой «фрактал» и для чего он и его замена используется?


    1. Helldar Автор
      26.08.2017 00:30
      -6

      Можно. Сам впервые услышал это название, когда наткнулся на статью)
      Конечно, можно загуглить, навести справки, но мне лень) Лучше код попишу используя то, что в статье написано.


    1. r-moiseev
      26.08.2017 10:31
      +1

      В 5.5 был добавлен интерфейс Responsable, делающий возможным выносить из контроллера логику формирования респонза. Вот собственно пример как это можно использовать.


      Раньше для этого (не все) использовали фрактал.


  1. yushkevichv
    26.08.2017 01:53

    Имеется ввиду вот этот фрактал, если неизвестно — fractal.thephpleague.com

    У пакета для апи dingo есть связка с ним для трансформеров данных.


  1. alexsoft
    26.08.2017 01:57

    А где Тейлор это представил? Где опубликовал?)


    1. r-moiseev
      26.08.2017 10:31

      На лараконе


  1. IgorVol
    26.08.2017 14:42
    -11

    Лет 5 назад ушёл с php на ruby, все время жалел, что не познакомился с ruby раньше. Слышал, что laravel многое перенял у rails. Сейчас посмотрел — нет, слава богу с php окончательно все законченно. Блин, даже js на интуитивном уровне приятнее и понятнее.


    1. satuevsky
      27.08.2017 00:58
      +3

      В смысле "даже"?


    1. Aios
      28.08.2017 11:54
      +2

      В аду для таких есть отдельный котел. А дорога туда выложена PHP-функциями.