Tidak semua proyek membutuhkan ORM, sistem form, dan template engine. Untuk API kecil, webhook, atau prototype yang hanya butuh routing dan middleware, framework lengkap justru membawa beban yang tidak dipakai. Slim Framework mengisi ceruk tersebut sebagai micro-framework: kerangka kerja minimal yang menyediakan router, middleware, dan integrasi dependency container — lalu menyerahkan sisanya kepada kita. Pada chapter ini kita membangun aplikasi Slim minimal, memahami request dan response berstandar PSR-7, middleware PSR-15, integrasi container, serta daftar hal yang memang harus kita susun sendiri.

Ceruk Micro-Framework #

Micro-framework mengambil definisi paling kecil dari “framework web”: menerima request, mencocokkan rute, menjalankan handler, mengembalikan response. Slim tidak membawa ORM, validasi, autentikasi, maupun template engine — dan itu disengaja. Filosofinya terbalik dari Laravel atau Symfony: framework besar berkata “semua sudah ada, singkirkan yang tidak perlu”, sedangkan Slim berkata “hampir tidak ada apa-apa, tambahkan yang Anda butuhkan”.

Ceruk ini nyata di banyak proyek. API internal dengan sepuluh endpoint, layanan webhook yang menerima notifikasi pembayaran, atau aplikasi kecil yang menempel pada sistem besar — semuanya lebih ringan ditulis pada kerangka yang transparan. Karena kode yang berjalan sedikit, jumlah hal yang perlu dipahami sebelum mengubah sesuatu juga sedikit; ini yang membuat micro-framework disenangi untuk layanan kecil yang harus mudah diaudit.

Aplikasi Minimal Slim #

Instalasi Slim 4 membutuhkan kerangka inti plus satu implementasi PSR-7 — Slim sengaja tidak memaksakan implementasi message HTTP tertentu:

bash
composer require slim/slim slim/psr7

Dengan dua paket tersebut, aplikasi lengkap yang bisa melayani request HTTP sudah cukup ditulis dalam satu berkas:

php
<?php
// public/index.php
require __DIR__ . '/../vendor/autoload.php';

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

$app = AppFactory::create();

$app->get('/halo/{nama}', function (Request $request, Response $response, string $nama) {
    $payload = json_encode(['pesan' => "Halo, $nama!"], JSON_UNESCAPED_UNICODE);
    $response->getBody()->write((string) $payload);

    return $response->withHeader('Content-Type', 'application/json');
});

$app->run();

Mari kita bedah aplikasi di atas baris per baris. Baris AppFactory::create() membangun instance aplikasi — factory ini membaca implementasi PSR-7 yang terpasang dan menyiapkan router. Method $app->get('/halo/{nama}', ...) mendaftarkan rute: pola URL, placeholder {nama}, dan closure handler. Closure menerima object Request, object Response, lalu parameter tambahan string $nama yang diisi otomatis dari placeholder rute — mekanisme identik dengan route parameter di Membuat Router . Handler menulis JSON ke body stream lewat $response->getBody()->write(), menambahkan header lewat withHeader(), lalu mengembalikan response. Baris terakhir $app->run() menjalankan seluruh siklus: menerima request, mencocokkan rute, mengeksekusi middleware dan handler, mengirim response.

Request dan Response PSR-7 #

Slim 4 tidak mendefinisikan interface HTTP miliknya sendiri. Request dan response yang mengalir melalui aplikasi adalah object berstandar PSR-7 — antarmuka pesan HTTP yang diterbitkan PHP-FIG, sehingga implementasi dari pihak mana pun bisa saling menggantikan. Standar ini adalah versi formal dari abstraksi yang kita bangun di Request-Response Abstractions :

php
<?php
$app->get('/artikel', function (Request $request, Response $response) {
    $halaman = (int) ($request->getQueryParams()['halaman'] ?? 1);
    $format = $request->getHeaderLine('Accept');

    $response->getBody()->write("Halaman $halaman, format $format");

    return $response;
});

Dua method pada handler di atas mewakili pekerjaan sehari-hari. Method getQueryParams() mengembalikan seluruh query string sebagai array — padanan $_GET yang kini berupa method object, dengan operasi ?? 1 untuk nilai bawaan. Method getHeaderLine('Accept') membaca satu header permintaan; padanan manualnya adalah mengurai $_SERVER['HTTP_ACCEPT']. Satu perilaku PSR-7 yang wajib diingat: object bersifat immutable. Method withHeader() tidak mengubah object lama melainkan mengembalikan salinan baru — itulah mengapa handler selalu return $response hasil modifikasi, bukan mengandalkan perubahan di tempat.

Middleware PSR-15 #

Cross-cutting concern — autentikasi API key, pencatatan log, kompresi — ditangani middleware berstandar PSR-15 . Konsep lapis bawang dan urutan eksekusinya sudah kita bangun sendiri di Middleware ; PSR-15 hanyalah versi distandarkan dari interface yang sama:

php
<?php
// src/Middleware/ApiKeyMiddleware.php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface as Handler;

final class ApiKeyMiddleware implements MiddlewareInterface
{
    public function process(Request $request, Handler $handler): Response
    {
        $apiKey = $request->getHeaderLine('X-Api-Key');

        if ($apiKey !== 'YOUR_API_KEY') {
            $response = new \Slim\Psr7\Response(401);
            $response->getBody()->write(json_encode(['error' => 'API key tidak valid']));

            return $response->withHeader('Content-Type', 'application/json');
        }

        return $handler->handle($request);
    }
}

Class di atas mengimplementasikan satu method process() yang menerima request dan handler berikutnya. Bila header X-Api-Key tidak cocok, middleware membangun response 401 sendiri dan mengembalikannya — request tidak pernah mencapai handler. Bila pemeriksaan lolos, $handler->handle($request) meneruskan request ke lapisan berikutnya dan response dari lapisan itu mengalir kembali lewat return. Pemasangannya satu baris, $app->add(ApiKeyMiddleware::class), dan karena standarnya terbuka, middleware PSR-15 dari paket Composer mana pun bisa dipakai tanpa penyesuaian.

Integrasi Dependency Injection Container #

Slim 4 memisahkan diri dari container bawaan: kerangka inti bisa berjalan tanpa container sama sekali, dan container apa pun yang mengimplementasikan PSR-11 bisa dipasang. Paket yang paling sering dipakai adalah PHP-DI berkat fitur autowiring-nya — container menebak dependensi dari type declaration, mirip perilaku service container Symfony pada chapter sebelumnya:

php
<?php
// public/index.php — integrasi PHP-DI
use Slim\Factory\AppFactory;

$container = new \DI\Container();
AppFactory::setContainer($container);

$app = AppFactory::create();

$app->get('/harga', function (Request $response_unused, Response $response, \App\Service\HargaService $harga) {
    $response->getBody()->write((string) $harga->totalBelanja(50000, 3));

    return $response;
});

Saat rute /harga dieksekusi, Slim memeriksa parameter tambahan pada closure di luar Request dan Response. Parameter bertipe HargaService diselesaikan lewat container: PHP-DI membaca constructor HargaService, menyuntikkan dependensinya, lalu menyerahkan instance ke handler — alur resolusi yang sama dengan Dependency Container buatan kita. Container juga bisa dipakai untuk konfigurasi eksplisit, misalnya mendaftarkan satu instance koneksi PDO agar seluruh handler memakai koneksi yang sama.

Yang Tidak Disediakan Slim #

Daftar hal yang harus kita tambahkan sendiri bukan kelemahan, melainkan ruang desain. Setiap baris pada tabel berikut adalah keputusan yang framework lengkap sudah ambilkan untuk kita:

KebutuhanSolusi umum di ekosistem Slim
DatabasePDO langsung, atau Doctrine ORM
Validasi inputsymfony/validator, atau respect/validation
Template HTMLTwig
AutentikasiMiddleware token JWT buatan sendiri, atau paket firebase/php-jwt
HTTP clientsymfony/http-client, atau Guzzle

Perhatikan bahwa solusi umum pada tabel justru mengarah kembali ke komponen Symfony dari chapter sebelumnya — symfony/validator dan symfony/http-client dipasang lewat Composer yang sama dan bekerja mulus di Slim. Pola pikir “framework mikro + komponen pilihan” inilah titik temu dua pendekatan ekosistem: kerangka yang memilih sendiri komponennya.

Kapan Slim Cocok #

SituasiKecocokan
API kecil hingga menengah (endpoint < 30)Sangat cocok — struktur ringan, cepat dimulai
Webhook dan integrasi antar sistemSangat cocok — sedikit dependensi, mudah diaudit
Prototype dan proof of conceptCocok — bisa tumbuh bertahap lewat komponen
Aplikasi web multi-fitur dengan admin, form, authKurang cocok — terlalu banyak yang disusun sendiri
Tim besar tanpa standar arsitektur bersamaHati-hati — struktur kode sepenuhnya menjadi tanggung jawab tim

Baris terakhir tabel tersebut adalah peringatan yang jujur: Slim tidak memaksakan struktur folder, layer, maupun konvensi penamaan. Kebebasan itu menyehatkan tim yang sudah punya disiplin, dan berbahaya bagi tim yang berharap framework menjaga kerapian untuk mereka. Disiplin yang sama persis dengan yang kita latih sepanjang section Arsitektur Aplikasi — controller tipis, service terpisah, domain bersih — tetap berlaku penuh di Slim.

Ringkasan #

Slim membuktikan bahwa framework bisa sangat kecil: satu factory, router berplaceholder, middleware PSR-15, dan ruang untuk container pilihan kita — sisanya disusun dari komponen terbaik ekosistem. Kini meja kita sudah memuat empat kandidat: Laravel yang kaya fitur, Symfony yang eksplisit dan berkomponen, Slim yang mikro, dan jalan tanpa framework yang kita tempuh sendiri di section Framework Development. Chapter berikutnya merangkum semuanya menjadi kerangka memilih framework secara rasional.

Referensi #