ข้ามไปยังเนื้อหา

การสร้าง API ด้วย Axum

ถ้าคุณมาจาก Node.js คุณคงรู้จัก Express หรือ NestJS แล้ว Axum คือคำตอบของ Rust สำหรับพื้นที่นั้น — เป็น web framework ระดับสูงที่ให้คุณเขียน async fn route handlers, วิเคราะห์ข้อมูล request ด้วย type-safe extractors และแชร์ state ข้ามหลาย routes

แต่ต่างจาก Express ตรงที่ Axum ไม่ได้รวมทุกอย่างมาในตัว ออกแบบมาให้บางแล้วโยนหน้าที่ middleware ให้ Tower ที่เป็น middleware library ระดับ production ที่ compose ได้ยืดหยุ่นมาก ผลที่ได้คือ:

  • Type safety ตั้งแต่ compile-time ตลอดทั้ง request/response cycle
  • Zero-cost abstractions — ไม่มี garbage collector ไม่มีการ allocation ที่ซ่อนอยู่
  • Async แบบ first-class สร้างบน Tokio ที่เป็น async runtime มาตรฐานของ Rust
ฟีเจอร์ExpressNestJSAxum
ภาษาTypeScript / JSTypeScriptRust
Routingapp.get(...)@Get(...) decoratorRouter::new().route(...)
Middlewareapp.use(...)@Middleware / guardsTower layers
วิเคราะห์ Requestreq.body, req.params@Body(), @Param()Extractors (Json, Path, Query)
Stateapp.localsDependency injectionState(...) extractor
จัดการ Errornext(err) middlewareException filtersResult<T, E> + IntoResponse
Type safetyบางส่วน (runtime)บางส่วน (runtime)เต็มรูปแบบ (compile-time)
TypeScript
// Express
import express from 'express';
const app = express();
app.get('/', (req, res) => {
res.json({ message: 'Hello, World!' });
});
app.listen(3000, () => console.log('Listening on :3000'));
Rust
use axum::{routing::get, Json, Router};
use serde_json::{json, Value};
async fn hello() -> Json<Value> {
Json(json!({ "message": "Hello, World!" }))
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(hello));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
println!("Listening on :3000");
axum::serve(listener, app).await.unwrap();
}

รันบนเครื่องของคุณ — Axum ผูก port และทำงานตลอดเวลา จึงไม่สามารถรันใน browser sandbox ได้ ใช้ cargo run หลังจากตั้งค่าโปรเจกต์ในบทถัดไป

ตลอดโมดูลนี้คุณจะสร้าง Users API ขนาดเล็กที่ประกอบด้วย:

  • GET /users — ดึงรายการ users (pagination ด้วย Query)
  • POST /users — สร้าง user ใหม่ (Json body)
  • GET /users/:id — ดึง user เดียว (Path)
  • DELETE /users/:id — ลบ user
  • Shared in-memory state (Arc<Mutex<Vec<User>>>)
  • JSON errors แบบมีโครงสร้าง
  • Tower CORS layer
  • SQLx database integration (เชิงแนวคิด)
  • Handler tests ด้วย tower::ServiceExt::oneshot

แต่ละแนวคิดเชื่อมโยงโดยตรงกับสิ่งที่คุณรู้จากอยู่แล้วจาก Express หรือ NestJS

Axum ใช้ async runtime ใด?
Axum จัดการ middleware อย่างไรเมื่อเทียบกับ Express?
อะไรคือสิ่งที่แทน `req.body` และ `req.params` ใน Axum?