API: Resource, JSON:API & Sanctum

Membangun REST API: API Resource untuk membentuk JSON, JSON:API Resources Laravel 13, dan autentikasi token dengan Sanctum.

Part 21 dari 26 ± 50 menit Gratis

Menyiapkan API

php artisan install:api      # membuat routes/api.php, menginstal Sanctum, menambah migrasi token

Route di routes/api.php otomatis berawalan /api dan tanpa session/CSRF (stateless): klien mengirim token di tiap permintaan.

API Resource: lapisan transformasi

Mengembalikan model Eloquent langsung (return $produk;) membocorkan semua kolom dan terikat pada struktur database. API Resource adalah lapisan di antara model dan JSON: kamu memutuskan persis bentuk responsnya.

php artisan make:resource ProdukResource
php artisan make:resource ProdukCollection --collection
<?php

namespace App\Http\Resources;

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

class ProdukResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id'           => $this->id,
            'nama'         => $this->nama,
            'slug'         => $this->slug,
            'harga'        => $this->harga,
            'harga_rupiah' => $this->harga_rupiah,          // accessor model
            'tersedia'     => $this->stok > 0,
            'kategori'     => new KategoriResource($this->whenLoaded('kategori')),   // hanya bila sudah dimuat
            'dibuat_pada'  => $this->created_at->toIso8601String(),
        ];
    }
}
  • $this->nama mengakses atribut model yang dibungkus.
  • whenLoaded('kategori') menyertakan relasi hanya jika sudah di-eager-load (mencegah N+1 tak sengaja).
  • Atribut kondisional: $this->when($user->isAdmin(), fn () => $this->harga_modal).

Memakai resource di controller

public function index()
{
    return ProdukResource::collection(Produk::with('kategori')->paginate(15));   // + meta & links paginasi otomatis
}

public function show(Produk $produk): ProdukResource
{
    return new ProdukResource($produk->load('kategori'));
}

Respons dibungkus dalam kunci data: { "data": { ... } }; koleksi berpaginasi menambah links dan meta. Cara singkat: $produk->toResource().

JSON:API Resources — baru di Laravel 13

Laravel 13 menyertakan JsonApiResource yang menghasilkan respons sesuai standar JSON:API (Content-Type: application/vnd.api+json), lengkap dengan id, type, attributes, relasi, sparse fieldsets, dan include.

php artisan make:resource PostResource --json-api
use Illuminate\Http\Resources\JsonApi\JsonApiResource;

class PostResource extends JsonApiResource
{
    public $attributes = ['title', 'body', 'created_at'];
    public $relationships = ['author', 'comments'];     // hanya disertakan bila klien meminta ?include=
}

Route::get('/api/posts/{post}', fn (Post $post) => new PostResource($post));   // GET /api/posts/1?include=author

Keluaran: { "data": { "id": "1", "type": "posts", "attributes": { ... } } }. Cocok bila klienmu (mis. pustaka front end) mengharapkan format JSON:API.

Autentikasi API: Laravel Sanctum

Sanctum menyediakan token API sederhana (dan autentikasi SPA berbasis cookie). Tambahkan trait ke model User:

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens;
}
// Login → menerbitkan token
public function login(Request $request): JsonResponse
{
    $user = User::where('email', $request->email)->first();

    if (! $user || ! Hash::check($request->password, $user->password)) {
        return response()->json(['pesan' => 'Kredensial salah'], 401);
    }

    return response()->json(['token' => $user->createToken('mobile')->plainTextToken]);
}

// Melindungi route
Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('produk', ProdukApiController::class);
});

Klien mengirim Authorization: Bearer <token>. Token hanya terlihat sekali (plainTextToken); database menyimpan hash-nya. Cabut: $user->currentAccessToken()->delete(). Batasi dengan abilities: createToken('mobile', ['produk:baca']) dan cek $user->tokenCan('produk:baca').

Praktik baik API

  • Versi API: Route::prefix('v1').
  • Kode status tepat (201, 204, 401, 403, 404, 422).
  • Paginasi untuk semua daftar; rate limiting (throttle:api).
  • Eager loading + whenLoaded untuk menghindari N+1.
  • Jangan pernah mengembalikan password/hash/token rahasia.

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X