Skip to content

2_7_Transformation for JSON response

YMHuang edited this page Jul 26, 2016 · 7 revisions

There is a transformation layer in VMS for transforming data into an array consistently and including nested relationship with other resource. It uses Fractal to implement the transformation.

The transformation layer includes transformers which are stored in app/Transformers/. Each transformer MUST inheritance League\Fractal\TransformerAbstract class and implement transform() which takes raw data and returns it into an Array.

Creating a transformer

In Fractal, there is a section to describe the transformer implementation.

For example, add a app/Transformers/ProjectTransformer.php file.

The ProjectTransformer inherits TransformerAbstract class and implements transform().

<?php

namespace App\Transformers;

use League\Fractal\TransformerAbstract;
use App\Project;

class ProjectTransformer extends TransformerAbstract
{
    public function transform(Project $project)
    {
        $item = $project->toArray();

        return $item;
    }
}

Default including data

If you would like to add nested relationship in transformer defaultly, like the project managers and project hyperlinks, the $defaultIncludes MUST be assigned in array and the elements are the relationship method names.

For example, the Project model has hyperlinks() and managers() for relationship with other models. They should be assigned into $defaultIncludes array and create includeXXX() method (XXX means the relationship method name), like includeManagers() and includeHyperlinks() methods.

<?php

namespace App\Transformers;

use League\Fractal\TransformerAbstract;
use App\Project;
use App\Transformers\ManagerTransformer;
use App\Transformers\ProjectHyperlinkTransformer;

class ProjectTransformer extends TransformerAbstract
{
    protected $defaultIncludes = [
        'managers',
        'hyperlinks'
    ];

    public function transform(Project $project)
    {
        $item = $project->toArray();

        return $item;
    }

    public function includeManagers(Project $project)
    {
        $managerCollection = $project->managers()->get();

        return $this->collection($managerCollection, new ManagerTransformer);
    }

    public function includeHyperlinks(Project $project)
    {
        $hyperlinkCollection = $project->hyperlinks()->get();

        return $this->collection($hyperlinkCollection, new ProjectHyperlinkTransformer);
    }
}

Send transformed data as a JSON response

There are two ways to send response to client. One is implemented by HTTP JSON response in Laravel. The other is implemented by Dingo API responses.

Here we use Dingo API responses to introduce.

The Project model instance is got by project id. It uses Response builder in Dingo API to return the response to client.

class ProjectController extends BaseAuthController
{
    public function show($id)
    {
        // Get the project model by $id
        $project = Project::findOrFail($id);

        // Ignore...

        return $this->response
                    ->item($project, new ProjectTransformer)
                    ->addMeta('role', $this->getRoleInProject($user, $project));
    }
}