Laravel transform response data with resource

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.