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'])
);