FastAPI快速上手:请求与响应的核心玩法

还在为构建高性能API而烦恼?知道吗,FastAPI框架的性能与NodeJSGo相当,同时提供极佳的开发体验。

📖 文章摘要

本文带你快速上手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"}

启动后,访问 http://127.0.0.1:8000/docs 即可看到交互式API文档,并直接测试所有端点!


---

喜欢本文?不要错过✨,点赞👍收藏⭐关注我👆,一起学习更多有用的知识,完善你我的技能树!

posted @ 2025-12-24 08:24  曲幽  阅读(138)  评论(0)    收藏  举报