FastAPI 教程(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在当今互联网时代,构建高效且可维护的 API 已成为开发者的核心需求。FastAPI 作为 Python 生态中新兴的异步框架,凭借其高性能、自动文档生成功能和直观的代码风格,迅速成为开发者们的热门选择。本文将通过循序渐进的方式,为编程初学者和中级开发者提供一份详尽的 FastAPI 教程,涵盖从环境搭建到实战部署的全流程,并穿插形象化比喻和代码示例,帮助读者轻松掌握这一工具。


一、FastAPI 的核心优势与适用场景

1.1 为什么选择 FastAPI?

FastAPI 的核心设计理念可以概括为三个关键词:快速开发者友好类型驱动

  • 快速:FastAPI 基于 Starlette 和 Pydantic,通过异步编程和高性能的底层实现,能够在处理高并发请求时保持低延迟。
  • 开发者友好:框架通过类型注解自动生成交互式 API 文档(Swagger UI),并提供直观的错误提示,大幅降低调试成本。
  • 类型驱动:通过 Python 的类型提示(Type Hints),FastAPI 能自动校验输入数据格式,减少手动验证的繁琐工作。

1.2 典型应用场景

FastAPI 适用于需要快速搭建 RESTful API 的场景,例如:

  • 构建微服务架构中的数据接口
  • 开发高并发的实时数据处理服务
  • 为移动应用或前端提供后端支持

比喻:如果将 API 比作一座桥梁,FastAPI 就像一座预制装配式桥梁——它通过标准化的组件(如自动文档、类型校验)快速搭建,让开发者无需从头设计每个细节,从而专注于业务逻辑。


二、环境搭建与第一个 API

2.1 安装 FastAPI

通过 pip 可以快速安装 FastAPI 及其依赖项:

pip install fastapi[all]  

此命令会安装 FastAPI、Uvicorn(异步服务器)和相关工具包。

2.2 编写第一个“Hello World”

创建文件 main.py,输入以下代码:

from fastapi import FastAPI  
app = FastAPI()  

@app.get("/")  
async def read_root():  
    return {"message": "Hello FastAPI!"}  

运行命令 uvicorn main:app --reload 后,访问 http://localhost:8000,即可看到自动生成的交互式文档,点击右上角的 Try it out 按钮即可测试接口。


三、基础路由与参数处理

3.1 路由定义与 HTTP 方法

FastAPI 支持通过装饰器定义不同 HTTP 方法的路由:

@app.get("/items/{item_id}")  
async def read_item(item_id: int):  
    return {"item_id": item_id}  

@app.post("/items/")  
async def create_item(item: dict):  
    return {"received": item}  
  • @app.get 对应 GET 请求,用于获取资源。
  • @app.post 对应 POST 请求,用于创建资源。

3.2 路径参数与查询参数

3.2.1 路径参数

通过 {} 定义动态路径参数,例如:

@app.get("/users/{user_id}")  
async def read_user(user_id: str):  
    return {"user_id": user_id}  

访问 http://localhost:8000/users/123 时,user_id 的值会被自动提取为字符串。

3.2.2 查询参数

通过函数参数直接接收查询参数:

@app.get("/search")  
async def search(q: str = None, limit: int = 10):  
    return {"query": q, "limit": limit}  

访问 http://localhost:8000/search?q=hello&limit=5 时,参数会被自动映射。


四、数据验证与序列化:Pydantic 的力量

4.1 Pydantic 模型基础

FastAPI 通过 Pydantic 的数据模型定义输入输出格式。例如,定义一个 Item 模型:

from pydantic import BaseModel  

class Item(BaseModel):  
    name: str  
    price: float  
    is_offer: bool = False  

在路由中使用该模型:

@app.post("/items/")  
async def create_item(item: Item):  
    return item  

此时,FastAPI 会自动校验请求体是否符合 Item 的字段要求,并返回友好错误提示。

4.2 嵌套模型与复杂数据结构

Pydantic 支持嵌套模型,例如:

class User(BaseModel):  
    id: int  
    name: str  

class Order(BaseModel):  
    user: User  
    items: list[Item]  

通过这种方式,可以轻松定义多层级的数据结构。


五、异步编程与并发处理

5.1 异步函数的定义

FastAPI 支持原生异步函数,通过 async def 声明:

@app.get("/async")  
async def read_async():  
    await some_async_operation()  # 模拟异步操作  
    return {"status": "done"}  

5.2 并发请求的优化

假设有一个需要调用外部 API 的场景:

import httpx  
async def fetch_data():  
    async with httpx.AsyncClient() as client:  
        response = await client.get("https://api.example.com/data")  
        return response.json()  

@app.get("/external")  
async def read_external():  
    data = await fetch_data()  
    return data  

通过异步 HTTP 客户端(如 httpx),可以避免阻塞其他请求,提升吞吐量。

比喻:同步编程如同排队点餐,每人必须等待前一位完成;而异步编程如同多线程服务,服务员可以同时处理多个订单,减少等待时间。


六、依赖注入与请求校验

6.1 依赖注入(Dependency Injection)

通过 Depends 实现代码复用和逻辑解耦:

def verify_token(token: str = Depends(oauth2_scheme)):  
    # 实现令牌验证逻辑  
    return user  

@app.get("/protected")  
async def protected_route(current_user: User = Depends(verify_token)):  
    return {"user": current_user}  

6.2 请求体校验与默认值

结合 Pydantic 模型和默认值:

class UpdateItem(BaseModel):  
    name: str | None = None  
    price: float | None = None  

@app.put("/items/{item_id}")  
async def update_item(item_id: int, item: UpdateItem):  
    stored_item = {"name": "default", "price": 0.0}  
    updated_item = stored_item.copy()  
    if item.name is not None:  
        updated_item["name"] = item.name  
    if item.price is not None:  
        updated_item["price"] = item.price  
    return updated_item  

七、实战案例:构建一个待办事项(Todo)API

7.1 需求分析

实现一个支持增删改查的 Todo 列表,包含以下功能:

  • 创建任务(POST)
  • 获取所有任务(GET)
  • 更新任务(PUT)
  • 删除任务(DELETE)

7.2 代码实现

7.2.1 数据模型

class TodoItem(BaseModel):  
    id: int  
    title: str  
    completed: bool = False  

7.2.2 路由定义

todos = []  # 模拟内存数据库  

@app.post("/todos/")  
async def create_todo(item: TodoItem):  
    todos.append(item)  
    return {"status": "success", "data": item}  

@app.get("/todos/")  
async def read_todos():  
    return {"todos": todos}  

@app.put("/todos/{item_id}")  
async def update_todo(item_id: int, item: TodoItem):  
    for i in range(len(todos)):  
        if todos[i].id == item_id:  
            todos[i] = item  
            return {"status": "updated"}  
    return {"error": "Item not found"}  

@app.delete("/todos/{item_id}")  
async def delete_todo(item_id: int):  
    global todos  
    todos = [item for item in todos if item.id != item_id]  
    return {"status": "deleted"}  

八、部署与性能优化

8.1 部署到生产环境

推荐使用 Uvicorn 结合 Nginx 或 Caddy 作为反向代理。例如:

gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app  

8.2 性能调优建议

  • 启用 HTTP/2:在 Uvicorn 中添加 --http=httptools 参数。
  • 缓存策略:使用 @cache 装饰器或第三方库(如 FastAPICache)。
  • 数据库连接池:通过异步数据库驱动(如 asyncpg)优化数据库交互。

结论

通过本文的 FastAPI 教程,读者已掌握了从环境搭建到实战部署的全流程,并理解了 FastAPI 在类型校验、异步编程和自动化文档方面的核心优势。无论是构建小型项目还是处理高并发需求,FastAPI 都能提供高效且优雅的解决方案。建议读者通过实践案例不断巩固知识,并参考官方文档探索更高级功能(如 WebSocket、OAuth2 认证等)。掌握 FastAPI,你将能够快速构建现代化、可维护的 API 服务,为后续的微服务架构或全栈开发打下坚实基础。

最新发布