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

Routing และ Parameters

ใน Express คุณเรียก app.get(path, handler) ใน FastAPI คุณตกแต่งฟังก์ชันด้วย @app.get(path) decorator นี้จะลงทะเบียนฟังก์ชันเป็น handler สำหรับ HTTP method + path combination นั้น ฟังก์ชันจะเป็น async def หรือ plain def ก็ได้

TypeScript
// Express
const app = express();
app.get('/items', (req, res) => {
res.json([{ id: 1, name: 'Widget' }]);
});
app.post('/items', (req, res) => {
const body = req.body; // parse เอง
res.status(201).json(body);
});
Python
# FastAPI
from fastapi import FastAPI
app = FastAPI()
@app.get("/items")
async def list_items():
return [{"id": 1, "name": "Widget"}]
@app.post("/items", status_code=201)
async def create_item(item: dict):
return item

FastAPI รองรับ HTTP methods มาตรฐานทั้งหมด: @app.get, @app.post, @app.put, @app.patch, @app.delete, @app.options

ครอบชื่อ parameter ด้วยวงเล็บปีกกาใน path string แล้วเพิ่ม argument ที่มี type ตรงกันในฟังก์ชัน FastAPI จะแปลงค่าให้และส่งคืน 422 Unprocessable Entity อัตโนมัติถ้าการแปลงล้มเหลว

TypeScript
// Express — ทุกอย่างเป็น string, แปลงเอง
app.get('/items/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
if (isNaN(id)) return res.status(422).json({ error: 'id must be integer' });
res.json({ id, name: 'Widget' });
});
// NestJS
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
return { id, name: 'Widget' };
}
Python
# FastAPI — type hint แปลง + validation
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def get_item(item_id: int): # GET /items/abc → 422 อัตโนมัติ
return {"id": item_id, "name": "Widget"}
# Path params หลายตัว
@app.get("/users/{user_id}/items/{item_id}")
async def get_user_item(user_id: int, item_id: int):
return {"user_id": user_id, "item_id": item_id}

argument ของฟังก์ชันตัวไหนที่ไม่ปรากฏใน path string FastAPI จะนับเป็น query parameter ให้อัตโนมัติ ถ้าอยากให้เป็น optional ก็ใส่ค่า default ไว้

TypeScript
// Express
app.get('/items', (req, res) => {
const skip = Number(req.query.skip) || 0;
const limit = Number(req.query.limit) || 10;
const q = req.query.q as string | undefined;
res.json({ skip, limit, q });
});
Python
# FastAPI — query params จาก function signature
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
@app.get("/items")
async def search_items(
skip: int = 0, # GET /items?skip=5
limit: int = 10, # GET /items?limit=20
q: Optional[str] = None, # GET /items?q=widget
):
return {"skip": skip, "limit": limit, "q": q}

browser ไม่สามารถรัน HTTP server จริงได้ แต่สามารถสำรวจวิธีที่ FastAPI จับคู่ handler ด้วย plain dict:

# Route registry — สะท้อนวิธีที่ FastAPI map handlers
routes = {
("GET", "/items"): "list_items",
("POST", "/items"): "create_item",
("GET", "/items/{id}"): "get_item",
("PUT", "/items/{id}"): "update_item",
("DELETE", "/items/{id}"): "delete_item",
}
def match_route(method: str, path: str) -> str:
# ตรงทั้งหมดก่อน
key = (method, path)
if key in routes:
return routes[key]
# template match (แบบง่าย)
for (m, tmpl), handler in routes.items():
if m != method:
continue
parts_tmpl = tmpl.split("/")
parts_path = path.split("/")
if len(parts_tmpl) != len(parts_path):
continue
if all(t.startswith("{") or t == p for t, p in zip(parts_tmpl, parts_path)):
return handler
return "404 Not Found"
tests = [
("GET", "/items"),
("POST", "/items"),
("GET", "/items/42"),
("DELETE", "/items/99"),
("GET", "/unknown"),
]
for method, path in tests:
print(f"{method:6s} {path:20s} -> {match_route(method, path)}")
FastAPI รู้ได้อย่างไรว่า function parameter เป็น path parameter หรือ query parameter?
FastAPI ส่ง HTTP status ใดถ้า client ส่ง GET /items/abc และ item_id มี type เป็น int?
จะทำให้ query parameter เป็น optional ใน FastAPI ได้อย่างไร?