乒耪普邻?? 文章摘要

本文带你快速上手FastAPI的请求与响应处理核心。你将清晰地掌握如何定义路由、处理GET/POST请求、玩转查询与路径参数、管理请求头与响应头、解析表单数据以及实现页面重定向。文末附有可直接运行的完整代码示例。

?? 你将学到:

- 路由与请求方法的基础定义

- 如何接收查询参数和路径参数

- 处理POST请求与JSON数据

- 读取请求头与设置自定义响应头

- 解析application/x-www-form-urlencoded表单数据

- 实现简单的重定向响应

? 目录

- ??? 第一步:从路由与请求方法开始

- ?? GET请求:查询参数与路径参数

- ?? POST请求:接收JSON与表单数据

- ?? 请求头与响应头:细节控制

- ?? 重定向:让请求跳转起来

- ?? 完整代码示例:一个迷你API服务

??? 第一步:从路由与请求方法开始

在FastAPI中,一切从app实例和装饰器开始。@app.get()、@app.post()等装饰器定义了URL路径和HTTP方法。

from fastapi import FastAPI

app = FastAPI()

# 定义一个处理根路径GET请求的路由

@app.get("/")

def read_root():

return {"message": "Hello, FastAPI World!"}

# 定义一个处理'/items'路径GET请求的路由

@app.get("/items/")

def read_items():

return [{"item_id": 1, "name": "Foo"}]

看,就这么简单!每个函数对应一个API端点,返回值自动转换为JSON响应。

?? GET请求:查询参数与路径参数

GET请求常用于获取数据,参数通常通过URL传递。主要有两种方式:查询参数和路径参数。

查询参数:跟在URL问号?后面,如/items/?skip=0&limit=10。在函数参数中声明即可自动获取。

@app.get("/items/")

def read_items(skip: int = 0, limit: int = 10):

# 模拟从数据库读取数据

fake_items = [{"item_id": i} for i in range(skip, skip + limit)]

return fake_items

路径参数:直接嵌在URL路径中,如/items/123。在路由中用{}声明。

@app.get("/items/{item_id}")

def read_item(item_id: int): # 类型注解会自动进行验证和转换

return {"item_id": item_id, "name": f"Item {item_id}"}

FastAPI的类型提示功能会帮你自动验证参数类型,并提供漂亮的API文档!

?? POST请求:接收JSON与表单数据

POST请求用于创建或提交数据。最常见的是接收JSON和表单数据。

1. 接收JSON数据:使用Pydantic模型来定义数据结构。

from pydantic import BaseModel

class Item(BaseModel):

name: str

description: str | None = None

price: float

tax: float | None = None

@app.post("/items/")

def create_item(item: Item): # 将请求体声明为Item类型

# 可以直接使用item的属性

item_dict = item.dict()

if item.tax:

total_price = item.price + item.tax

item_dict.update({"total_price": total_price})

return item_dict

2. 接收表单数据:当数据来自HTML表单时,使用Form。

from fastapi import Form

@app.post("/login/")

def login(username: str = Form(...), password: str = Form(...)):

# Form(...)表示必填字段

return {"username": username, "login_status": "success"}

注意:使用Form前需要先安装python-multipart库。

?? 请求头与响应头:细节控制

有时你需要读取客户端的请求头,或者为响应添加自定义头部信息。

读取请求头:使用Header函数。

from fastapi import Header

@app.get("/headers/")

def read_headers(user_agent: str | None = Header(None)):

return {"User-Agent": user_agent}

设置响应头:返回一个Response对象,或在依赖中设置。

from fastapi import Response

@app.get("/custom-header/")

def set_custom_header(response: Response):

response.headers["X-Custom-Header"] = "MyCustomValue"

return {"message": "Check the headers!"}

?? 重定向:让请求跳转起来

重定向在Web开发中很常见,比如登录后跳转到首页。使用RedirectResponse即可轻松实现。

from fastapi.responses import RedirectResponse

@app.get("/old-link/")

def old_link():

# 永久重定向到新的URL

return RedirectResponse(url="/new-link/", status_code=301)

@app.get("/new-link/")

def new_link():

return {"message": "This is the new endpoint!"}

?? 完整代码示例:一个迷你API服务

将上面的知识点整合,创建一个简单的笔记API。保存为main.py,然后用uvicorn main:app --reload运行它!

from fastapi import FastAPI, Path, Query, Header, Form, Response

from fastapi.responses import RedirectResponse

from pydantic import BaseModel

from typing import Optional

app = FastAPI(title="迷你笔记API")

# 数据模型

class Note(BaseModel):

title: str

content: str

# 模拟数据库

fake_notes_db = [{"id": 1, "title": "First Note", "content": "Hello!"}]

# 首页重定向到文档

@app.get("/")

def home():

return RedirectResponse(url="/docs")

# 获取所有笔记 (带查询参数分页)

@app.get("/notes/")

def get_notes(skip: int = Query(0, ge=0), limit: int = Query(10, le=100)):

return fake_notes_db[skip : skip + limit]

# 根据ID获取特定笔记 (路径参数)

@app.get("/notes/{note_id}")

def get_note_by_id(note_id: int = Path(..., title="笔记ID", gt=0)):

for note in fake_notes_db:

if note["id"] == note_id:

return note

return {"error": "Note not found"}

# 创建新笔记 (POST JSON)

@app.post("/notes/")

def create_note(note: Note, response: Response):

new_id = max([n["id"] for n in fake_notes_db], default=0) + 1

new_note = {"id": new_id, **note.dict()}

fake_notes_db.append(new_note)

response.headers["Location"] = f"/notes/{new_id}"

response.status_code = 201

return new_note

# 一个需要User-Agent头的端点

@app.get("/check-agent/")

def check_user_agent(user_agent: Optional[str] = Header(None)):

return {"received_user_agent": user_agent}

# 表单登录示例

@app.post("/login-form/")

def login_form(username: str = Form(...), password: str = Form(...)):

# 这里应该有真实的验证逻辑

if username == "admin" and password == "secret":

return {"message": "Login successful"}

return {"message": "Invalid credentials"}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐