paint-brush
First impressions on Laravel API Resourcesby@deleu
11,256 reads
11,256 reads

First impressions on Laravel API Resources

by Marco Aurélio DeleuAugust 24th, 2017
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Last night <a href="https://medium.com/@taylorotwell" data-anchor-type="2" data-user-id="d694c31ce941" data-action-value="d694c31ce941" data-action="show-user-card" data-action-type="hover" target="_blank">Taylor Otwell</a> finally introduced what can be the beginning of replacing <a href="http://fractal.thephpleague.com/transformers/" target="_blank">Fractal</a> when developing APIs on Laravel 5.5. This is my first trial-and-run at it.
featured image - First impressions on Laravel API Resources
Marco Aurélio Deleu HackerNoon profile picture

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.

1- Install clean Laravel 5.5 project







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

2- Prepping the database

  • The posts migration 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();});

  • The Post 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);}];});

  • The User has Posts relationship app/User.php




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

  • Avoid Mass Assignment on Posts app/Post.php

**<?php

namespace** App;

use Illuminate\Database\Eloquent\Model;




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

  • Seeding the database




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

3- Setup the Route

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

4- Transforming Model into a Resource










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

5- Users With Posts Resource

**<?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- Posts Resource

**<?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- Conclusion

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.

Followup

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