什么是HTTP状态码?¶
HTTP状态码是服务器向客户端返回的数字代码,用于表示请求的处理结果。比如“200”表示请求成功,“404”表示请求的资源不存在。在FastAPI中,正确设置状态码能帮助API客户端(如前端、其他服务)准确理解请求结果,是构建健壮API的基础。
FastAPI中如何设置状态码?¶
FastAPI提供了两种常用方式设置状态码:
1. 直接在路由函数返回时指定:通过元组 (数据, 状态码) 返回。
2. 使用HTTPException异常:抛出带有状态码和错误信息的异常(推荐用于错误场景)。
示例代码(两种方式对比):
from fastapi import FastAPI, HTTPException
app = FastAPI()
# 方式1:直接返回元组
@app.get("/hello")
def say_hello():
return {"message": "Hello"}, 200 # 返回200 OK
# 方式2:抛出HTTPException(错误场景)
@app.get("/users/{user_id}")
def get_user(user_id: int):
if user_id != 1:
raise HTTPException(
status_code=404,
detail="User not found"
)
return {"user_id": user_id, "name": "Alice"}
常见状态码及使用场景¶
以下是初学者最常用的状态码,附简单示例帮助理解:
1. 200 OK:请求成功¶
场景:GET/POST/PUT等请求处理成功时返回,返回具体数据或结果。
示例:查询存在的用户信息:
fake_users_db = {1: {"name": "Alice"}, 2: {"name": "Bob"}}
@app.get("/users/{user_id}")
def get_user(user_id: int):
if user_id in fake_users_db:
return fake_users_db[user_id] # 自动返回200 OK
raise HTTPException(status_code=404, detail="User not found") # 不存在返回404
2. 404 Not Found:资源不存在¶
场景:请求的资源(如ID、路径)不存在时返回,常见于GET/DELETE请求找不到目标。
示例:请求不存在的用户ID:
@app.get("/users/{user_id}")
def get_user(user_id: int):
if user_id not in fake_users_db:
return {"error": "User not found"}, 404 # 返回404
return fake_users_db[user_id]
3. 500 Internal Server Error:服务器内部错误¶
场景:服务器代码出错、数据库连接失败等服务器端问题时返回(尽量避免暴露给用户,应捕获异常返回友好提示)。
错误示例(避免):
@app.get("/crash")
def crash():
1 / 0 # 故意制造错误,FastAPI默认返回500(但实际应捕获!)
正确处理:用try-except捕获并返回400等具体错误:
from fastapi import HTTPException
@app.get("/divide")
def divide(a: float, b: float):
try:
return a / b
except ZeroDivisionError:
raise HTTPException(status_code=400, detail="除数不能为0")
4. 201 Created:资源创建成功¶
场景:POST请求创建新资源(如新增用户、商品)成功时返回,需返回新资源的信息。
示例:创建新用户:
@app.post("/users")
def create_user(new_user: dict): # 假设接收新用户数据
new_id = 3 # 数据库新增ID
created_user = {"id": new_id, **new_user}
return created_user, 201 # 返回201和创建的用户
5. 204 No Content:无内容返回¶
场景:DELETE/PUT请求成功但无需返回数据(如删除资源后),仅返回状态码。
示例:删除用户:
from fastapi import status
@app.delete("/users/{user_id}")
def delete_user(user_id: int):
if user_id in fake_users_db:
del fake_users_db[user_id]
return {"message": "User deleted"}, status.HTTP_204_NO_CONTENT # 204无内容
raise HTTPException(status_code=404, detail="User not found")
6. 400 Bad Request:请求参数错误¶
场景:请求参数不合法(如必填字段缺失、格式错误)时返回。
示例:提交负数价格(Pydantic模型验证):
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
@app.post("/items")
def create_item(item: Item):
if item.price < 0:
raise HTTPException(status_code=400, detail="价格不能为负数")
return item, 201
7. 401 Unauthorized / 403 Forbidden¶
- 401:未认证(用户未登录)。
示例:访问需登录的接口:
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def get_current_user(token: str = Depends(oauth2_scheme)):
if not token: # 假设token不存在则未认证
raise HTTPException(status_code=401, detail="未认证")
@app.get("/profile")
def get_profile(user=Depends(get_current_user)):
return {"message": "已登录"}
- 403:已认证但权限不足(如普通用户访问管理员接口)。
示例:普通用户访问管理员接口:
async def get_admin_role(user: dict = Depends(get_current_user)):
if user.get("role") != "admin":
raise HTTPException(status_code=403, detail="权限不足")
@app.get("/admin")
def admin_route(user=Depends(get_admin_role)):
return {"message": "管理员数据"}
最佳实践:不同HTTP方法的状态码习惯¶
- GET:查询数据,成功返回200,失败返回404(资源不存在)或400(参数错误)。
- POST:创建资源,成功返回201,参数错误返回400。
- PUT/PATCH:更新资源,成功返回200或204,失败返回400/404。
- DELETE:删除资源,成功返回204,失败返回404。
总结¶
状态码是API的“语言”,正确使用能让客户端清晰理解请求结果。FastAPI通过status_code参数和HTTPException简化了状态码设置,初学者需重点掌握200(成功)、404(资源不存在)、500(服务器错误)、201(创建成功)、400(参数错误)等核心状态码的场景,避免因状态码混乱导致前端或下游服务错误。
(注:FastAPI自动生成的Swagger文档会显示路由的状态码,调试时可通过文档直观查看各接口的状态码定义。)