
Прошлой ночью 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 migrationSchema::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.phppublic 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.
От переводчика
Посчитал эту тему интересной и решил перевести с адаптацией языка. Прошу ногами не пинать. Также приветствуются линки на оригинальную и переведенную доку по данной тематике.
