0%

FastAPI自学教程(73) - OpenAPI回调机制

1.基础用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from fastapi import APIRouter, FastAPI
from pydantic import BaseModel, HttpUrl

app = FastAPI()

class Invoice(BaseModel):
id: str
customer: str
total: float

class InvoiceEvent(BaseModel):
description: str
paid: bool

invoices_callback_router = APIRouter()

@invoices_callback_router.post(
"{$callback_url}/invoices/{$request.body.id}",
response_model=dict
)
def invoice_notification(body: InvoiceEvent):
pass

@app.post("/invoices/", callbacks=invoices_callback_router.routes)
def create_invoice(invoice: Invoice, callback_url: HttpUrl = None):
"""创建发票并触发回调"""
return {"msg": "Invoice received"}
  • 通过callbacks参数将回调路由附加到主路径操作
  • 回调路径使用OpenAPI表达式动态生成URL(如{$callback_url}{$request.body.id}
  • 处理流程:
    graph TD
      A[客户端请求主API] --> B[处理业务逻辑]
      B --> C[生成回调请求]
      C --> D[发送到callback_url]
      D --> E[外部API处理]
      E --> F[返回主API结果]

2.回调路径表达式

2.1 动态URL生成

  • {$callback_url}:来自查询参数的值
  • {$request.body.id}:从主请求体中提取发票ID
  • 示例最终回调URL:https://external.com/events/invoices/123

2.2 参数来源类型

表达式格式 数据来源
{$request.query.param} 主请求的查询参数
{$request.body#/key} 主请求体的JSON字段
{$response.body#/key} 主响应的JSON字段

3.回调文档生成

  • 自动生成Swagger UI文档,展示回调接口规范
  • 回调路径操作无需实际代码,仅用于文档说明
  • 文档显示位置:主API的/docs页面中的”Callbacks”部分

4.实际回调实现

1
2
3
4
5
6
7
8
9
10
import httpx

async def real_callback(url: str, data: dict):
async with httpx.AsyncClient() as client:
response = await client.post(url, json=data)
response.raise_for_status()
return response.json()

# 在主业务逻辑中调用
await real_callback(callback_url, {"status": "paid"})
  • 需要单独实现HTTP请求逻辑
  • 推荐使用httpx.AsyncClient进行异步调用
  • 错误处理需包含重试机制和超时设置

5.生产环境建议

  1. 异步处理:使用背景任务防止阻塞主流程
  2. 安全验证
    • 校验回调URL域名白名单
    • 添加请求签名验证(如HMAC)
  3. 错误监控
    • 记录回调失败次数和原因
    • 设置最大重试次数(建议3次)
  4. 性能优化
    • 使用连接池保持长连接
    • 限制并发回调数量(Semaphore)

测试命令示例:

1
2
3
curl -X POST "http://localhost:8000/invoices/?callback_url=https://api.external.com" \
-H "Content-Type: application/json" \
-d '{"id":"INV-2024","customer":"ABC Corp","total":999.99}'