laravelapijsonresourceMenengah3 mnt baca

API Resource: Format Respons JSON

Ubah model jadi JSON yang konsisten dengan API Resource, termasuk relasi bersyarat.

Kenapa tidak return model langsung?

Kamu bisa saja return Post::all() dan Laravel otomatis mengubahnya jadi JSON. Tapi hasilnya menampilkan SEMUA kolom termasuk yang sensitif, dan strukturnya berubah-ubah. API Resource memberi kamu kontrol penuh atas bentuk respons.

bash
php artisan make:resource PostResource
php
// app/Http/Resources/PostResource.php
namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'judul' => $this->judul,
            'slug' => $this->slug,
            'ringkasan' => str($this->isi)->limit(150),
            'status' => $this->status,
            'penulis' => $this->whenLoaded('user', fn () => $this->user->nama),
            'diterbitkan_pada' => $this->created_at->toDateTimeString(),
        ];
    }
}

Memakai resource

php
use App\Http\Resources\PostResource;

// Satu item
return new PostResource($post);

// Koleksi (otomatis jadi data array)
return PostResource::collection($posts);

// Dengan pagination (meta pagination ikut otomatis)
return PostResource::collection(Post::paginate(15));

Hasil JSON-nya selalu konsisten:

json
{
    "data": [
        { "id": 1, "judul": "...", "penulis": "Omni" }
    ],
    "links": { "first": "...", "last": "...", "prev": null, "next": "..." },
    "meta": { "current_page": 1, "total": 42 }
}

Trik yang sering dipakai

whenLoaded: hanya tampilkan relasi kalau sudah di-eager-load, mencegah N+1 tidak sengaja.

when: tampilkan field berdasarkan kondisi:

php
'email' => $this->when($request->user()?->is_admin, $this->email),

mergeWhen: gabungkan beberapa field sekaligus secara kondisional.

Catatan teknis: Jangan memanggil relasi langsung di dalam toArray\) tanpa whenLoaded, misalnya 'penulis' => $this->user->nama. Kalau resource dipakai untuk 100 item tanpa eager load, itu 100 query tambahan. Selalu pasangkan dengan Post::with('user')` di controller.