Skip to content

OldMusketeers/laravel-fractal

 
 

Repository files navigation

A Fractal service provider for Laravel 5 and Lumen

Latest Version on Packagist Software License Build Status SensioLabsInsight Quality Score Total Downloads

The package provides a nice and easy integration with Fractal for your Laravel 5 and Lumen projects. If you don't know what Fractal does, take a peek at their intro. Shortly said, Fractal is very useful to transform data before using it in an API.

Using Fractal data can be transformed like this:

use League\Fractal\Manager;
use League\Fractal\Resource\Collection;

$books = [
   ['id'=>1, 'title'=>'Hogfather', 'characters' => [...]], 
   ['id'=>2, 'title'=>'Game Of Kill Everyone', 'characters' => [...]]
];

$manager = new Manager();

$resource = new Collection($books, new BookTransformer());

$manager->parseIncludes('characters');

$manager->createData($resource)->toArray();

This package makes that process a tad easier:

fractal()
   ->collection($books)
   ->transformWith(new BookTransformer())
   ->includeCharacters()
   ->toArray();

Lovers of facades will be glad to know that a facade is provided:

Fractal::collection($books)->transformWith(new BookTransformer())->toArray();

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Install

You can pull in the package via composer:

$ composer require spatie/laravel-fractal

Next up, the service provider must be registered:

// Laravel5: config/app.php
'providers' => [
    ...
    Spatie\Fractal\FractalServiceProvider::class,

];

or, if you are using Lumen:

// Lumen: bootstrap/app.php
$app->register(Spatie\Fractal\FractalLumenServiceProvider::class);

If you want to make use of the facade you must install it as well:

// config/app.php
'aliases' => [
    ...
    'Fractal' => Spatie\Fractal\FractalFacade::class,
];

If you want to change the default serializer, you must publish the config file:

php artisan vendor:publish --provider="Spatie\Fractal\FractalServiceProvider"

This is the contents of the published file:

return [

    /*
    |--------------------------------------------------------------------------
    | Default Serializer
    |--------------------------------------------------------------------------
    |
    | The default serializer to be used when performing a transformation. It
    | may be left empty to use Fractal's default one. This can either be a
    | string or a League\Fractal\Serializer\SerializerAbstract subclass.
    |
    */

    'default_serializer' => '',

];

Usage

In the following examples were going to use the following array as example input:

$books = [['id'=>1, 'title'=>'Hogfather'], ['id'=>2, 'title'=>'Game Of Kill Everyone']];

But know that any structure that can be looped (for instance a collection) can be used.

Let's start with a simple transformation.

fractal()
   ->collection($books)
   ->transformWith(function($book) { return ['id' => $book['id']];})
   ->toArray();

This will return:

['data' => [['id' => 1], ['id' => 2]]

Instead of using a closure you can also pass a Transformer:

fractal()
   ->collection($books)
   ->transformWith(new BookTransformer())
   ->toArray();

To make your code a bit shorter you could also pass the transform closure or class as a second parameter of the collection-method:

fractal()->collection($books, new BookTransformer())->toArray();

Want to get some sweet json output instead of an array? No problem!

fractal()->collection($books, new BookTransformer())->toJson();

A single item can also be transformed:

fractal()->item($books[0], new BookTransformer())->toArray();

##Using a serializer

Let's take a look again a the output of the first example:

['data' => [['id' => 1], ['id' => 2]];

Notice that data-key? That's part of Fractal's default behaviour. Take a look at Fractals's documentation on serializers to find out why that happens.

If you want to use another serializer you can specify one with the serializeWith-method. The Spatie\Fractal\ArraySerializer comes out of the box. It removes the data namespace for both collections and items.

fractal()
   ->collection($books)
   ->transformWith(function($book) { return ['id' => $book['id']];})
   ->serializeWith(new \Spatie\Fractal\ArraySerializer())
   ->toArray();

//returns [['id' => 1], ['id' => 2]]

Changing the default serializer

You can change the default serializer by providing the classname or an instantiation of your favorite serializer in the config file.

Using includes

Fractal provides support for optionally including data on the relationships for the data you're exporting. You can use Fractal's parseIncludes which accepts a string or an array:

fractal()
   ->collection($this->testBooks, new TestTransformer())
   ->parseIncludes(['characters', 'publisher'])
   ->toArray();

To improve readablity you can also a function named include followed by the name of the include you want to... include:

fractal()
   ->collection($this->testBooks, new TestTransformer())
   ->includeCharacters()
   ->includePublisher()
   ->toArray();

Including meta data

Fractal has support for including meta data. You can use addMeta which accepts one or more arrays:

fractal()
   ->collection($this->testBooks, function($book) { return ['name' => $book['name']];})
   ->addMeta(['key1' => 'value1'], ['key2' => 'value2'])
   ->toArray();

This will return the following array:

[
   'data' => [
        ['title' => 'Hogfather'],
        ['title' => 'Game Of Kill Everyone'],
    ],
   'meta' => [
        ['key1' => 'value1'], 
        ['key2' => 'value2'],
];

Using pagination

Fractal provides a Laravel-specific paginator, IlluminatePaginatorAdapter, which accepts an instance of Laravel's LengthAwarePaginator and works with paginated Eloquent results. When using some serializers, such as the JsonApiSerializer, pagination data can be automatically generated and included in the result set:

$paginator = Book::paginate(5);
$books = $paginator->getCollection();

fractal()
    ->collection($books, new TestTransformer())
    ->serializeWith(new JsonApiSerializer())
    ->paginateWith(new IlluminatePaginatorAdapter($paginator))
    ->toArray();

Setting a custom resource name

Certain serializers wrap the array output with a data element. The name of this element can be customized:

fractal()
    ->collection($this->testBooks, new TestTransformer())
    ->serializeWith(new JsonApiSerializer())
    ->resourceName('books')
    ->toArray();
fractal()
    ->item($this->testBooks[0], new TestTransformer(), 'book')
    ->serializeWith(new JsonApiSerializer())
    ->toArray();

Change log

Please see CHANGELOG for more information what has changed recently.

Testing

$ composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email freek@spatie.be instead of using the issue tracker.

Credits

About Spatie

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

License

The MIT License (MIT). Please see License File for more information.

Packages

No packages published

Languages

  • PHP 100.0%