Belajar Rust - Networking Dasar dan HTTP Server
Series/Belajar Rust/Episode 10
Episode 10 of 19

Belajar Rust - Networking Dasar dan HTTP Server

Episode ini membangun HTTP server pertama di Rust dengan axum, membahas request-response, routing, middleware, dan error handling, lalu mengenal koneksi TCP dan UDP dasar serta konsep service discovery untuk aplikasi terdistribusi.

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

Pendahuluan

Setelah menguasai data dan konfigurasi, saatnya aplikasi Rust kalian berbicara dengan dunia luar. Episode 10 adalah titik di mana program kalian berubah menjadi service nyata: menerima request HTTP, memprosesnya, dan mengembalikan respons.

Kita mulai dari dasar jaringan dengan std::net, lalu membangun HTTP server dengan axum — framework modern di atas hyper. Kalian akan belajar routing, middleware, error handling, serta melihat sekilas warp, actix-web, dan konsep service discovery. Di akhir episode, kalian punya API yang bisa diuji dengan curl.

Dasar TCP dan UDP

Socket di Standard Library

Sebelum HTTP, pahami transport-nya: TCP menyediakan koneksi andal berurutan, UDP menyediakan datagram cepat tanpa jaminan. Standard library menyediakan keduanya:

TCP listener
cat > src/main.rs <<'EOF'
use std::io::{Read, Write};
use std::net::TcpListener;
 
fn main() {
    let listener = TcpListener::bind("127.0.0.1:8000").unwrap();
    println!("mendengarkan di 127.0.0.1:8000");
 
    for stream in listener.incoming() {
        let mut stream = stream.unwrap();
        let mut buffer = [0; 1024];
        stream.read(&mut buffer).unwrap();
        let respons = b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok";
        stream.write_all(respons).unwrap();
    }
}
EOF
cargo run

TcpListener::bind("127.0.0.1:8000") membuka port lokal, dan listener.incoming() menghasilkan koneksi masuk. Contoh di atas bahkan sudah merespons HTTP — meskipun sangat primitif. cargo run lalu uji dengan curl http://127.0.0.1:8000 dari terminal lain.

UDP untuk Latency Kritis

UDP dipakai untuk DNS, telemetri, dan game karena overheadnya minimal. Di Rust, UdpSocket::bind dan send_to/recv_from menangani datagram. Untuk HTTP dan service bisnis, TCP tetap pilihan utama.

HTTP Server dengan Axum

Membangun Server Pertama

axum dibangun di atas hyper dan tower, memakai arsitektur handler dan extractor yang ekspresif. Tambahkan dependency dengan cargo add axum tokio --features tokio/full:

Hello world axum
cat > src/main.rs <<'EOF'
use axum::{routing::get, Router};
 
async fn halo() -> &'static str {
    "Halo dari axum"
}
 
#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(halo));
 
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
        .await
        .unwrap();
 
    println!("listening on 127.0.0.1:3000");
    axum::serve(listener, app).await.unwrap();
}
EOF
cargo run

Router::new().route("/", get(halo)) mendaftarkan handler ke path. axum::serve menjalankan server async. Uji dengan curl http://127.0.0.1:3000 dan kalian akan melihat respons Halo dari axum.

Extractor dan Response

Handler menerima extractor seperti Path, Query, Json, dan State, serta mengembalikan tipe apa pun yang mengimplementasi IntoResponse:

Path dan JSON
cat > src/main.rs <<'EOF'
use axum::{extract::Path, routing::get, Json, Router};
use serde::Serialize;
 
#[derive(Serialize)]
struct Pengguna {
    id: u32,
    nama: String,
}
 
async fn detail(Path(id): Path<u32>) -> Json<Pengguna> {
    Json(Pengguna {
        id,
        nama: format!("pengguna {}", id),
    })
}
 
#[tokio::main]
async fn main() {
    let app = Router::new().route("/api/pengguna/{id}", get(detail));
 
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
        .await
        .unwrap();
 
    axum::serve(listener, app).await.unwrap();
}
EOF
cargo run

Path(id): Path<u32> mengambil nilai dari segmen {id}. Json<Pengguna> membuat respons JSON dari struct ber-Serialize. Uji dengan curl http://127.0.0.1:3000/api/pengguna/7.

Routing, Middleware, dan Error Handling

Middleware dengan tower

Middleware menangani concern lintas request: logging, timeout, CORS, dan kompresi. axum memakai lapisan dari tower:

Layer trace dan fallback
use tower_http::trace::TraceLayer;
 
let app = Router::new()
    .route("/", get(|| async { "selamat datang" }))
    .layer(TraceLayer::new_for_http())
    .fallback(|| async { (StatusCode::NOT_FOUND, "tidak ditemukan") });

TraceLayer mencatat setiap request beserta status dan durasi. fallback menangani path yang tidak terdaftar. Layer dipasang dengan .layer(...) dan diterapkan dari luar ke dalam.

Error Handling Handler

Handler mengembalikan Result<T, E> di mana E: IntoResponse:

Handler dengan error
struct AppError(anyhow::Error);
 
impl IntoResponse for AppError {
    fn into_response(self) -> Response {
        (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("terjadi kesalahan: {}", self.0),
        )
    }
}
 
async fn index() -> Result<&'static str, AppError> {
    Ok("api sehat")
}

Error dari handler dikonversi menjadi respons HTTP dengan status yang sesuai. Operator ? di dalam handler mempropagasi error internal, dan AppError mengubahnya menjadi respons yang ramah klien.

Framework Lain dan Service Discovery

warp, actix-web, dan hyper

Selain axum: warp memakai filter combinators yang komposable, actix-web menawarkan model aktor dan performa tinggi, sedangkan hyper adalah fondasi HTTP rendah yang dipakai axum sendiri. Pilih axum untuk ekosistem tokio, actix-web untuk tim yang ingin framework semua-dalam-satu, dan warp untuk gaya fungsional.

Service Discovery

Di lingkungan terdistribusi, instance service tidak saling tahu alamatnya. Service discovery menyelesaikan ini: instance mendaftarkan diri ke registry (misalnya etcd, Consul, atau registry bawaan Kubernetes), dan konsumen menanyakan registry untuk menemukan alamat aktif. Di Rust, crate seperti rust-consul dan tonic (untuk gRPC) menjadi jembatan menuju ekosistem ini.

Penutup

Inti yang harus dibawa pulang:

  • std::net menyediakan TCP dan UDP dasar; TCP untuk layanan andal.
  • axum membangun server HTTP di atas hyper dan tower.
  • Router, handler, dan extractor seperti Path, Query, dan Json membentuk API.
  • Middleware tower menangani concern lintas request seperti trace dan timeout.
  • Error handler dikonversi menjadi respons HTTP dengan status yang tepat.
  • warp dan actix-web adalah alternatif; service discovery menghubungkan instance.

Di episode 11 selanjutnya kita akan membahas keamanan, TLS, dan auth — mengaktifkan HTTPS dengan TLS dan sertifikat, implementasi autentikasi JWT, OAuth2, dan session, serta proteksi input, CORS, rate limiting, dan security header. API kalian siap dihadirkan ke publik.

Belajar Rust - Networking Dasar dan HTTP Server | Belajar Rust