Belajar Swoole - HTTP Server Dasar
Episode 4 of 26

Belajar Swoole - HTTP Server Dasar

Membangun HTTP server pertama dengan Swoole\Http\Server, memahami objek Request dan Response, siklus event on Request, routing manual tanpa framework, pengaturan port dan host, serta perbedaan lifecycle dengan PHP-FPM yang terlihat dari perilaku state di dalam worker.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 3 kita berhasil menginstall dan memverifikasi Swoole, pada episode ini kita membangun fondasi paling nyata: HTTP server dengan Swoole\Http\Server. Ini adalah jenis server yang paling sering dipakai di dunia nyata — setiap API, setiap aplikasi web long-running, berawal dari sini.

Mengapa episode ini penting? Karena inilah momen kalian merasakan perbedaan PHP-FPM secara langsung: kode handler yang sama dieksekusi ribuan kali di dalam proses yang sama, state bertahan antar request, dan koneksi TCP dikelola oleh event loop. Kesalahan yang kalian lakukan di sini akan menghantui seluruh series, jadi mari kita bangun dengan benar.

Hello World: HTTP Server Pertama

Kode paling sederhana untuk memulai:

server.php - HTTP server hello world
<?php
use Swoole\Http\Server;
use Swoole\Http\Request;
use Swoole\Http\Response;
 
$server = new Server('0.0.0.0', 9501);
 
$server->on('Request', function (Request $req, Response $res) {
    $res->header('Content-Type', 'text/plain');
    $res->end('Hello from Swoole!');
});
 
$server->start();

Jalankan dan uji:

Jalankan server dan tes
php server.php
Dari terminal lain
curl http://127.0.0.1:9501/

on('Request') adalah jantung HTTP server: dipanggil untuk setiap request HTTP yang masuk, menerima objek Swoole\Http\Request (permintaan) dan Swoole\Http\Response (jawaban). $res->end() menutup response — wajib dipanggil tepat sekali per request.

Memahami Objek Request

Objek Request memuat seluruh informasi HTTP yang kalian kenal dari $_GET, $_POST, dan $_SERVER:

PropertiSetara PHP-FPMIsi
$req->get$_GETParameter query string
$req->post$_POSTBody form-urlencoded
$req->server$_SERVERInfo server (request_method, request_uri, remote_addr)
$req->header$_SERVER['HTTP_*']Header request
$req->cookie$_COOKIECookie
$req->getContent()file_get_contents('php://input')Raw body

Contoh membaca data request:

Membaca parameter request
$server->on('Request', function (Request $req, Response $res) {
    $name = $req->get['name'] ?? 'dunia';
    $ua = $req->header['user-agent'] ?? 'unknown';
    $res->end("Halo $name! User-Agent: $ua");
});

Note

Dalam coroutine context, memanggil $_GET/$_POST global di aplikasi Swoole adalah anti-pattern. Selalu ambil data dari objek Request. Framework seperti Hyperf melakukan ini secara konsisten — kita lihat di episode 15.

Membangun Response

Objek Response memberi kontrol penuh atas output:

Response dengan header dan JSON
$server->on('Request', function (Request $req, Response $res) {
    $res->status(200);
    $res->header('Content-Type', 'application/json');
    $res->header('X-Powered-By', 'Swoole');
    $res->end(json_encode(['status' => 'ok']));
});

Metode penting Response:

  • $res->status($code) — set HTTP status code.
  • $res->header($k, $v) — set response header.
  • $res->cookie($k, $v, $expire) — set cookie.
  • $res->write($chunk) — tulis sebagian response (untuk streaming / chunked).
  • $res->end($data) — selesaikan response.
  • $res->redirect($url, $code) — redirect HTTP (episode 18).

Routing Manual Tanpa Framework

Tanpa framework, routing adalah tanggung jawab kita sendiri. Pola paling bersih: parse request_uri, lalu dispatch ke handler:

Router manual sederhana
<?php
use Swoole\Http\Server;
use Swoole\Http\Request;
use Swoole\Http\Response;
 
$routes = [
    '/'          => fn (Request $req, Response $res) => $res->end('Home'),
    '/health'    => fn (Request $req, Response $res) => $res->end('OK'),
    '/api/users' => fn (Request $req, Response $res) => $res->end('[{"id":1}]'),
];
 
$server = new Server('0.0.0.0', 9501);
 
$server->on('Request', function (Request $req, Response $res) use ($routes) {
    $path = rtrim($req->server['request_uri'] ?? '/', '/');
    $path = $path === '' ? '/' : $path;
 
    if (isset($routes[$path])) {
        $routes[$path]($req, $res);
    } else {
        $res->status(404);
        $res->end('Not Found');
    }
});
 
$server->start();

Perhatikan request_method juga perlu dicek bila ingin membedakan GET/POST untuk path yang sama — detail ini kita naikkan levelnya di episode 5 dengan regex routes dan middleware.

State Bertahan Antar Request

Inilah perbedaan paling terasa dengan PHP-FPM. Variabel di luar handler hidup terus selama worker hidup:

State persist antar request
$server = new Server('0.0.0.0', 9501);
$hits = 0; // hidup selama worker hidup
 
$server->on('Request', function (Request $req, Response $res) use (&$hits) {
    $hits++;
    $res->end("Hits: $hits");
});

Jalankan dan refresh berulang kali — counter terus naik. Di PHP-FPM counter akan selalu 1. Tapi ingat pelajaran episode 2: $hits hanya bertahan per worker. Dengan banyak worker, angka yang kalian lihat bergantung worker mana yang menangani request. State lintas worker memakai Swoole\Table/Atomic (episode 12).

Pengaturan Host dan Port

Konstruktor server bisa menerima beberapa konfigurasi:

Server dengan konfigurasi dasar
$server = new Server('0.0.0.0', 9501, SWOOLE_PROCESS);
$server->set([
    'worker_num'     => 4,
    'max_request'    => 10000,
    'log_file'       => '/tmp/swoole.log',
    'dispatch_mode'  => 2,
]);
OpsiArti
worker_numJumlah worker proses
max_requestRequest maksimal per worker sebelum direcycle
log_fileLokasi log server
dispatch_modeCara distribusi request ke worker (detail episode 20)

Common Pitfalls

  • Response ganda: memanggil end() dua kali menyebabkan error. Pastikan satu jalur eksekusi per request.
  • Lupa start(): server tidak akan berjalan tanpa memanggil start() di akhir.
  • Port bentrok: curl timeout padahal server jalan? Cek port dengan ss -tlnp.
  • Error tidak terlihat: default error Swoole dicetak ke stderr — periksa terminal tempat php server.php berjalan, bukan browser.

Penutup

Pada episode 4 ini, kalian telah membangun HTTP server pertama dan memahami fondasinya.

Inti yang harus dibawa pulang:

  • Swoole\Http\Server + on('Request') adalah pola dasar HTTP di Swoole.
  • Data request diambil dari objek Request, output dikontrol objek Response.
  • Routing manual: parse request_uri, dispatch ke handler, 404 untuk yang tidak cocok.
  • State hidup antar request di dalam satu worker — beda total dengan PHP-FPM.
  • Konfigurasi dasar: worker_num, max_request, dispatch_mode, log_file.

Di episode 5 selanjutnya, kita menaikkan level HTTP server: routing lanjutan dengan static & regex routes serta middleware — CORS, logging, dan error handling yang rapi. Sampai jumpa di episode 5!

Belajar Swoole - HTTP Server Dasar | Belajar Swoole