Simple Eloquent and Collection transformation. Useful for ensuring that your API outputs are consistent and preventing code duplication., (*1)
Installation
Install the package using composer:, (*2)
composer require lukevear/laravel-transformer
To register the package with Laravel, add the collowing to config/app.php
:, (*3)
LukeVear\LaravelTransformer\TransformerServiceProvider::class,
Optionally install the configuration file:, (*4)
php artisan vendor:publish --provider="LukeVear\LaravelTransformer\TransformerServiceProvider"
Creating transformers is easy. Simply extend the AbstractTransformer
class and implement your required logic., (*5)
Transformers only require a run
method. The run
method is where you will implement any logic required to transform your model/collection., (*6)
For example, the below could be used to create a consistent 'User API model' for clients to consume., (*7)
The Transformer, (*8)
<?php
namespace App\Transformers;
use App\User;
use LukeVear\LaravelTransformer\AbstractTransformer;
class UserTransformer extends AbstractTransformer
{
/**
* Transform the supplied data.
*
* @param User $model
* @return array
*/
public function run($model)
{
return [
'id' => $model->id,
'name' => $model->first_name . ' ' . $model->last_name
];
}
}
Usage, (*9)
return response()->json(
transform($user, new UserTransformer)
);
You can optionally specify which transformer to use for each Model in your codebase, and specify which 'group' of transformers to use., (*10)
To setup automatic transformation, edit config/laravel-transformer.php
(ensure you ran the vendor:publish command above)., (*11)
For example, if you have a v1
and v2
API, you may have the following in your configuration file:, (*12)
<?php
return [
/*
|--------------------------------------------------------------------------
| Model <-> Transformer Binding Groups
|--------------------------------------------------------------------------
|
| This allows you to specify which transformers should automatically be
| used when the transform() function is provided a Eloquent model.
|
*/
'groups' => [
'default' => [
// App\User::class => App\Transformers\UserTransformer::class,
],
'v1' => [
App\Models\User::class => App\Transformers\v1\UserTransformer::class,
],
'v2' => [
App\Models\User::class => App\Transformers\v2\UserTransformer::class,
],
],
];
In your global middleware you can then specify which transformation group to use depending on the API version being consumed:, (*13)
public function handle($request, Closure $next)
{
if ($request->is('v1*')) {
TransformerEngine::setGroup('v1');
} else {
TransformerEngine::setGroup('v2');
}
return $next($request);
}
You can then transform your User model in any controller using the following:, (*14)
return response()->json(
transform($user)
);
Inclusions
When manually creating a transformer you can optionally supply additional 'includes' that provide context to the transformer., (*15)
For example, you may wish to include the user's settings model alongside the user model. To achieve this you could implement something like this:, (*16)
```php
<?php, (*17)
namespace App\Transformers;, (*18)
use App\User;
use LukeVear\LaravelTransformer\AbstractTransformer;, (*19)
class UserTransformer extends AbstractTransformer
{
/**
* Transform the supplied data.
*
* @param User $model
* @return array
*/
public function run($model)
{
$response = [
'id' => $model->id,
'name' => $model->first_name . ' ' . $model->last_name
];, (*20)
if ($this->hasInclude('settings')) {
$response['settings'] = transform($model->settings, new UserSettingsTransformer);
}
return $response;
}
}
```, (*21)
To tell the transformer that you wish to include settings, you'd use the following in your route/controller:, (*22)
return response()->json(
transform($user, (new UserTransformer)->setIncludes(['settings'])
);