Last night Taylor Otwell finally introduced what can be the beginning of replacing Fractal when developing APIs on Laravel 5.5. This is my first trial-and-run at it.
The interesting stuff starts at step 4.
composer create-project laravel/laravel responses dev-developcd responsestouch database/database.sqlitephp artisan make:model Post -mfaphp artisan make:resource UsersWithPostsResourcephp artisan make:resource PostsResourcephp artisan make:controller UsersController --resource
Change your .env
file to use SQLite and remove every other database variable.
DB_CONNECTION=sqlite
database/migrations/______create_posts_table.php
Schema::create('posts', function (Blueprint $table) {$table->increments('id');$table->string('title');$table->string('body');$table->unsignedInteger('user_id');$table->timestamps();});
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);}];});
app/User.php
public function posts(){return $this->hasMany(Post::class);}
app/Post.php
**<?php
namespace** App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model{protected $guarded = [];}
php artisan migrate:freshphp artisan tinkerfactory(App\Post::class)->times(2)->create();factory(App\Post::class)->times(2)->create(['user_id' => 1]);
Route::apiResource('/users', 'UsersController');
/*** Display a listing of the resource.** @param User $user* @return _\Illuminate\Http\Response*/_public function index(User $user){return new UsersWithPostsResource($user->paginate());}
**<?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)
\];
});
}
}
**<?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];});}}
The first clear difference when comparing to Fractal is that the resource have easy and direct access to the whole collection instead of a per-object basis. This means that when transforming a collection of Users, you can easily eager load every post without N+1 queries.
It is also easy to nest transformation since you can just spawn a new Resource class that will transform your data as needed.
I expect to write a more detailed post about it once I start digging more into the possibilities.
This was the first article on API Resources coming to Laravel 5.5. You can find the 2nd article on this subject here: https://medium.com/@deleugpn/reusable-api-resource-with-nested-relationship-laravel-5-5-c654c7243869