Прошлой ночью 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)
yushkevichv
26.08.2017 01:53Имеется ввиду вот этот фрактал, если неизвестно — fractal.thephpleague.com
У пакета для апи dingo есть связка с ним для трансформеров данных.
IgorVol
26.08.2017 14:42-11Лет 5 назад ушёл с php на ruby, все время жалел, что не познакомился с ruby раньше. Слышал, что laravel многое перенял у rails. Сейчас посмотрел — нет, слава богу с php окончательно все законченно. Блин, даже js на интуитивном уровне приятнее и понятнее.
ange007
Балин…
Вообще ничего не понял. Что/куда и для чего?
Можно ведь было добавить от переводчика предисловие — что за такой «фрактал» и для чего он и его замена используется?
Helldar Автор
Можно. Сам впервые услышал это название, когда наткнулся на статью)
Конечно, можно загуглить, навести справки, но мне лень) Лучше код попишу используя то, что в статье написано.
r-moiseev
В 5.5 был добавлен интерфейс Responsable, делающий возможным выносить из контроллера логику формирования респонза. Вот собственно пример как это можно использовать.
Раньше для этого (не все) использовали фрактал.