โ† Semua pembelajaran / Laravel Nol โ†’ Enterprise
Fase 1 ยท Request, Routing & Blade

HTTP Request

Objek Request membungkus semua superglobal PHP jadi satu API yang bisa diuji. Yang penting bukan daftar method-nya, melainkan kebiasaan mengambil input dengan tipe yang benar.

Sumber asli laravel.com Resmi Rangkuman ~6 menit baca

Intisari

  • $request->input('kunci', $default) membaca query string maupun body, tanpa peduli metodenya.
  • Pakai method bertipe: integer(), boolean(), date(), enum() โ€” bukan cast manual.
  • $request->validated() hanya mengembalikan field yang lolos aturan. Itulah satu-satunya yang aman masuk ke create().
  • Berkas unggahan adalah objek UploadedFile; simpan dengan store(), jangan pernah percaya nama aslinya.
  • Di balik proxy (ALB, CloudFront), IP dan skema HTTPS hanya benar kalau trusted proxy dikonfigurasi.

Membaca input

public function cari(Request $request)
{
    $kata    = $request->input('q', '');           // query string atau body
    $halaman = $request->integer('page', 1);       // sudah int, bukan string
    $aktif   = $request->boolean('aktif');         // "1", "true", "on", "yes" โ†’ true
    $mulai   = $request->date('mulai');            // Carbon, atau null
    $status  = $request->enum('status', StatusPesanan::class);

    $semua   = $request->all();                    // seluruh input โ€” jangan dipakai untuk mass assignment
    $sedikit = $request->only(['q', 'kategori']);
    $tanpa   = $request->except(['_token']);

    if ($request->filled('q')) { /* ada DAN tidak kosong */ }
    if ($request->has('q'))    { /* ada, meski kosong */ }
    if ($request->missing('q')) { /* tidak ada sama sekali */ }
}

Kenapa method bertipe itu penting. Semua input HTTP sampai ke PHP sebagai string. $request->input('page') menghasilkan "2", bukan 2. Dengan strict_types aktif, mengoper string itu ke parameter int adalah error; tanpa itu, ia lolos diam-diam sampai suatu perbandingan berperilaku aneh. $request->integer('page') menyelesaikan keduanya sekaligus.

Konteks permintaan

$request->user();                  // model User, atau null
$request->user()?->id;

$request->path();                  // "produk/12"
$request->url();                   // tanpa query string
$request->fullUrl();               // dengan query string
$request->method();                // "POST"
$request->isMethod('post');

$request->header('Accept');
$request->bearerToken();           // isi header Authorization: Bearer โ€ฆ
$request->ip();
$request->expectsJson();           // penting untuk error handler
$request->routeIs('admin.*');

Berkas unggahan

if ($request->hasFile('foto') && $request->file('foto')->isValid()) {

    // store() membuat nama acak dan aman. JANGAN pakai getClientOriginalName().
    $path = $request->file('foto')->store('produk', 's3');

    // atau dengan nama yang kamu tentukan sendiri
    $path = $request->file('foto')->storeAs('produk', $produk->id.'.jpg', 's3');
}

Tiga hal yang tidak boleh dipercaya dari berkas unggahan: namanya (bisa berisi ../../ atau .php), MIME type yang dikirim klien (dipalsukan dalam satu detik), dan ukurannya menurut klien. Validasi dengan aturan File::image()->max(2048) yang memeriksa isi berkasnya, bukan klaimnya โ€” dan simpan di S3, bukan di dalam public/.

Di balik load balancer

Begitu aplikasimu berjalan di belakang ALB atau CloudFront (Fase 9), $request->ip() akan mengembalikan IP load balancer, dan $request->isSecure() akan bilang false meski pengguna memakai HTTPS. Akibatnya: rate limiting per-IP jadi salah sasaran, dan tautan yang dibuat url() memakai http://.

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(
        at: '*',                                   // di VPC, hanya ALB yang bisa menjangkau task
        headers: Request::HEADER_X_FORWARDED_FOR
               | Request::HEADER_X_FORWARDED_HOST
               | Request::HEADER_X_FORWARDED_PORT
               | Request::HEADER_X_FORWARDED_PROTO,
    );
})

at: '*' hanya aman kalau tidak ada yang bisa menghubungi aplikasimu langsung. Kalau kontainer bisa dicapai dari internet tanpa melewati load balancer, siapa pun bisa memalsukan X-Forwarded-For dan menembus rate limit. Di Fase 9 hal ini dijamin oleh security group: hanya ALB yang boleh membuka port aplikasi.

Menguji tanpa browser

$response = $this->postJson('/api/produk', [
    'nama'  => 'Kopi',
    'harga' => 25000,
]);

$response->assertCreated()->assertJsonPath('data.nama', 'Kopi');

Karena Request adalah objek biasa, seluruh siklus HTTP bisa dijalankan di dalam tes tanpa server. Ini yang membuat suite tes Laravel cepat, dan dibahas tuntas di Fase 6.

Latihan: buat rute /echo yang mengembalikan $request->all(), lalu kirimi ia curl "localhost:8000/echo?page=2&aktif=on". Amati bahwa page berupa string "2". Ganti responsnya jadi $request->integer('page') dan $request->boolean('aktif'), lalu bandingkan keluarannya.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.