以fastapi为例理解学习http的错误码规范

343 阅读2分钟

HTTP 状态码的规范主要来源于 RFC 7231,该规范是 HTTP/1.1 的一部分。不同的状态码和相关行为可能还涉及其他 RFC。以下是一些关键的 RFC 规范及其内容:

主要的 HTTP 状态码规范

  1. RFC 7231 (HTTP/1.1: Semantics and Content)

    • 定义了最常用的状态码,包括 200 OK、400 Bad Request、404 Not Found 等。
    • 涵盖了 HTTP 方法(GET、POST、PUT 等)及其语义。
  2. RFC 7232 (HTTP/1.1: Conditional Requests)

    • 涉及条件请求的状态码,例如 304 Not Modified。
  3. RFC 7233 (HTTP/1.1: Range Requests)

    • 定义了 206 Partial Content 和范围请求的语义。
  4. RFC 7235 (HTTP/1.1: Authentication)

    • 涉及身份验证相关的状态码,例如 401 Unauthorized 和 407 Proxy Authentication Required。
  5. RFC 6585

    • 引入了一些扩展状态码,例如:

      • 428 Precondition Required
      • 429 Too Many Requests
      • 431 Request Header Fields Too Large
  6. RFC 7725

    • 定义了状态码 451 Unavailable For Legal Reasons,用于表示因法律原因无法提供的资源。

RFC 编号与状态码对照表

状态码描述来源 RFC
200OKRFC 7231
201CreatedRFC 7231
204No ContentRFC 7231
301Moved PermanentlyRFC 7231
302FoundRFC 7231
304Not ModifiedRFC 7232
400Bad RequestRFC 7231
401UnauthorizedRFC 7235
403ForbiddenRFC 7231
404Not FoundRFC 7231
405Method Not AllowedRFC 7231
500Internal Server ErrorRFC 7231
502Bad GatewayRFC 7231
503Service UnavailableRFC 7231
429Too Many RequestsRFC 6585
451Unavailable For Legal ReasonsRFC 7725

如何查阅相关 RFC

  • IETF 官网:所有 RFC 的官方文档可通过 RFC Editor 查阅。
  • 快速访问:如需具体状态码的详情,可以通过网址模式 https://datatracker.ietf.org/doc/html/rfcXXXX 查看(替换 XXXX 为具体的 RFC 编号)。

使用 FastAPI 生成错误码的示例

以下是一个使用 FastAPI 定义和返回自定义 HTTP 状态码的示例:

from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse

app = FastAPI()

# 自定义异常处理器
@app.exception_handler(HTTPException)
async def custom_http_exception_handler(request, exc):
    return JSONResponse(
        status_code=exc.status_code,
        content={"message": exc.detail, "code": exc.status_code},
    )

# 示例路由
@app.get("/resource/{item_id}")
async def read_item(item_id: int):
    if item_id == 0:
        raise HTTPException(
            status_code=404, detail="Resource not found"
        )
    elif item_id < 0:
        raise HTTPException(
            status_code=400, detail="Invalid item ID"
        )
    return {"item_id": item_id, "status": "success"}

# 示例扩展状态码
@app.get("/rate-limited")
async def rate_limited():
    raise HTTPException(
        status_code=429, detail="Too many requests"
    )

输出示例

  1. 请求不存在的资源:
GET /resource/0

{
  "message": "Resource not found",
  "code": 404
}
  1. 请求 ID 无效:
GET /resource/-1

{
  "message": "Invalid item ID",
  "code": 400
}
  1. 请求速率限制:
GET /rate-limited

{
  "message": "Too many requests",
  "code": 429
}