2_7_Transformation for JSON response - OpenISDM/VMS GitHub Wiki
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));
}
}