In Laravel there a built-in way to transform your response data to map it to a newly response different from the database fields.
Create resource with artisan command
For example we want to transform article response so we named it ArticleDetailResource to create the ArticleDetailResource type the command below
php artisan make:resource ArticleDetailResource
Implementation
In your app/Http/Resources you will see ArticleDetailResource.php. To transform any response data that we need to transform just write all the logic in the toArray() function the function return an associative array. See full example below.
<?php
namespace App\Http\Resources;
use App\Http\Resources\CategoryResource;
use Illuminate\Http\Resources\Json\JsonResource;
class ArticleDetailResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content,
'category' => $this->category ? new CategoryResource($this->category) : [],
'tags' => $this->tags ? TagResource::collection($this->tags) : []
];
}
}
What special is that you can point to relation that you already create in the model and transform using another Resource. See example below.
In the app/Models/Article.php
<?php
namespace App\Models;
use App\Models\Tag;
use App\Models\Category;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
protected $table = 'articles';
protected $fillable = ['title', 'content', 'category_id'];
public function category()
{
return $this->belongsTo(Category::class);
}
public function tags()
{
return $this->belongsToMany(
Tag::class,
"article_tags",
'article_id',
'tag_id'
);
}
}
Usage
In controller where you want to transform the response data use it by calling the ArticleDetailResource. This will response the transform data from resource.
use App\Http\Resources\ArticleDetailResource;
public function show($id)
{
try {
$data = Article::findOrFail($id);
$response = new ArticleDetailResource($data);
return response()->json([ 'data' => $response ]);
} catch (\Throwable $th) {
throw $th;
}
}
Conclusion
Laravel resource feature allows you to transform response data not just that, what is special is that you can point to another relation of model instance and transform another resource. This allows you full flexibility to transform any type of data you want.