HTTP协议与RESTful API实战手册(二):用披萨店故事说透API设计奥秘 🍕
title: HTTP协议与RESTful API实战手册(二):用披萨店故事说透API设计奥秘 🍕
| 外卖步骤 | HTTP对应概念 | 示例 |
|---|---|---|
| 顾客下单 | POST请求 | POST /orders |
| 打印小票 | Header元数据 | Content-Type: application/json |
| 后厨制作 | 服务器处理逻辑 | 数据库写入操作 |
| 外卖异常通知 | 4xx/5xx状态码 | 404 披萨缺货 |
@app.post("/orders")
async def create_order():
try:
# 处理订单逻辑
return JSONResponse(201, headers={"Location": "/orders/1001"})
except OutOfStock:
return JSONResponse(409, content={"error": "玛格丽特披萨库存不足"})
# 错误:动词导向 ❌
@app.post("/getUserOrders")
def get_orders(): ...
# 正确:名词导向 ✅
@app.get("/users/{user_id}/orders")
def get_orders(user_id: int): ...
// 订单创建响应
{
"id": 1001,
"status": "烤制中",
"_links": {
"self": {"href": "/orders/1001", "method": "GET"},
"cancel": {"href": "/orders/1001", "method": "DELETE"}
}
}
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Pizza(BaseModel):
name: str
price: float
size: Literal["S", "M", "L"]
# 菜单管理
@app.get("/pizzas")
async def list_pizzas(): ...
@app.post("/pizzas")
async def create_pizza(pizza: Pizza): ...
# 订单系统
@app.post("/orders")
async def create_order(pizza_ids: list[int]): ...
# 案例:忘记必填参数
@app.post("/pizzas")
async def create_pizza(pizza: Pizza):
# 如果客户端未传price字段...
# 客户端收到响应:
{
"detail": [
{
"loc": ["body", "price"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
# 危险写法 ❌
def get_order(raw_id: str):
query = f"SELECT * FROM orders WHERE id = {raw_id}"
# 安全写法 ✅
def get_order_safe(order_id: int):
query = "SELECT * FROM orders WHERE id = :id"
params = {"id": order_id}
from fastapi import Request
from fastapi_cache import FastAPICache
from fastapi_cache.decorator import cache
@app.get("/pizzas/{pizza_id}")
@cache(expire=60) # 缓存60秒
async def get_pizza(pizza_id: int):
return db.query(Pizza).filter(Pizza.id == pizza_id).first()
# 你的挑战:
@app.get("/orders/{order_id}/tracking")
async def get_delivery_status(order_id: int):
# 返回配送状态和骑手位置
pass
# 需求:
# - 创建促销活动(POST /promotions)
# - 限制每个用户参与次数
# - 过期活动自动关闭


评论
发表评论