API Resource — Laravel

API Resource mentransformasi model Eloquent menjadi format JSON yang rapi. Membuat resource: php artisan make:resource UserResource class UserResource extends…

API Resource adalah class yang mengubah model Eloquent jadi JSON dengan bentuk yang kamu tentukan sendiri. Bayangin arsip anggota di meja petugas perpustakaan. Lembar arsipnya lengkap: nomor HP, catatan denda, status petugas. Kartu anggota yang kamu pegang cuma memuat nama, nomor anggota, dan tanggal bergabung, dengan tata letak yang sama untuk semua anggota. Model itu lembar arsipnya, baris lengkap dari database. Resource itu pencetak kartunya: dia memilih field mana yang keluar dan merapikan bentuknya.

🧪 Tebakan cepat: controller menulis return new UserResource($user);. JSON yang diterima client diawali {"id": 1, ...} atau {"data": {"id": 1, ...}}? Tebak dulu, jawabannya ada di bagian "Satu, banyak, dan per halaman".

Kenapa gak return model langsung

Laravel bisa mengubah model jadi JSON tanpa bantuan. Route ini mengembalikan user Budi apa adanya:

Route::get('/api/users/{id}', fn ($id) => User::find($id));
{"id":1,"name":"Budi","email":"[email protected]","phone":"081234567890","is_admin":0,"created_at":"2026-03-14T09:30:00.000000Z","updated_at":"2026-03-14T09:30:00.000000Z"}

password dan remember_token gak ikut, karena model User bawaan Laravel sudah menandai keduanya sebagai tersembunyi. Tapi kolom lain ikut semua: nomor HP anggota dan is_admin bocor ke siapa pun yang membuka alamat ini, tanggalnya berbentuk mentah dengan mikrodetik, dan bentuk JSON-nya ikut berubah tiap kali tabelnya berubah. Resource membalik caranya: cuma field yang kamu tulis yang keluar.

Membuat resource

php artisan make:resource UserResource
<?php

namespace App\Http\Resources;

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

class UserResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'member_since' => $this->created_at->format('Y-m-d'),
        ];
    }
}

Satu, banyak, dan per halaman

Resource dipakai di controller dengan tiga cara. Datanya tiga anggota perpustakaan: Budi, Ani, Citra.

Di controller JSON yang diterima client
return new UserResource(User::find(1)); {"data":{"id":1,"name":"Budi","email":"[email protected]","member_since":"2026-03-14"}}
return UserResource::collection(User::all()); {"data":[{...Budi},{...Ani},{...Citra}]}
return UserResource::collection(User::paginate(2)); data berisi Budi dan Ani, ditambah links dan meta

Resource paling luar selalu dibungkus key data. Jadi JSON-nya diawali {"data": {...}}. Itu jawaban tebakannya. Untuk banyak model, pakai UserResource::collection(...), bukan new UserResource(...). Hasil paginate(2) membawa keterangan halaman:

"links": {
    "first": "http://127.0.0.1:8000/api/users?page=1",
    "last": "http://127.0.0.1:8000/api/users?page=2",
    "prev": null,
    "next": "http://127.0.0.1:8000/api/users?page=2"
},
"meta": { "current_page": 1, "from": 1, "last_page": 2, "path": "http://127.0.0.1:8000/api/users", "per_page": 2, "to": 2, "total": 3, "links": [...] }

Di halaman 2, next jadi null dan prev berisi alamat halaman 1. Cara kerja halaman sendiri dibahas di pelajaran Pagination.

Field bersyarat: when dan whenLoaded

return [
    'id' => $this->id,
    'name' => $this->name,
    'phone' => $this->when($request->user()?->is_admin, $this->phone),
    'loans' => LoanResource::collection($this->whenLoaded('loans')),
];

Di latihan

Kode awal sudah punya class UserResource extends JsonResource dengan toArray($request) yang kosong. Isi array-nya dengan id, name, email dan member_since. Simulator latihan memuat class-nya lalu mencetak Class defined: UserResource. Isinya dinilai dari kodenya: harus ada $this->..., ->format( dan Y-m-d.

⚠️ Jebakan yang sering ketemu

TL;DR: API Resource memilih dan merapikan field yang keluar dari model. Buat dengan php artisan make:resource UserResource, turunkan dari JsonResource, lalu kembalikan array di toArray($request): 'id' => $this->id, 'member_since' => $this->created_at->format('Y-m-d'). Kolom yang gak ditulis gak pernah keluar. Satu model: return new UserResource($user). Banyak model: return UserResource::collection(User::all()). Hasilnya dibungkus {"data": ...}, dan paginate() menambahkan links dan meta. $this->when(syarat, nilai) menghilangkan key saat syaratnya false, $this->whenLoaded('loans') cuma menampilkan relasi yang sudah dimuat dengan with('loans').

Yang akan kamu pelajari