1. 为什么选择FastAPI?一个开发者的真实感受
如果你和我一样,用Python写过Web应用,那你肯定绕不开Flask和Django。Flask轻巧灵活,Django大而全,但它们都有一个共同点:在构建现代API,特别是需要高性能和异步支持的API时,总感觉差了那么点意思。要么是性能瓶颈,要么是异步支持不够原生,写起来有点别扭。
直到我遇到了FastAPI。说实话,第一次用的时候,我被它的开发体验惊艳到了。写一个接口,代码还没写完,交互式API文档就已经自动生成了,而且类型提示带来的代码补全和错误检查,让开发效率直接拉满。后来在几个高并发的物联网数据采集和实时分析项目里用了FastAPI,它的性能表现更是让我彻底成了它的粉丝。它基于Starlette和Pydantic,性能直逼Go和Node.js,但写起来还是我们熟悉的Python味道。
所以,FastAPI到底是什么?简单说,它是一个用于构建API的现代、快速(高性能)的Web框架。它特别适合用来创建RESTful API,也就是我们今天要聊的主题。它“快”在哪里?一方面是运行时性能极高,另一方面是开发速度极快。官方说能提升200%到300%的开发速度,减少40%的人为错误,我实测下来,这个说法并不夸张。尤其是当你需要频繁和前端对接接口文档时,自动生成的OpenAPI文档能省下大量沟通和写文档的时间。
它最适合谁呢?我认为是以下几类开发者:一是正在从Flask/Django转型,想尝试更现代、性能更好框架的Python后端开发者;二是需要快速构建原型或微服务,对开发效率有极高要求的团队;三是项目涉及大量I/O操作(比如数据库查询、调用外部API),希望用异步提升性能的开发者。如果你符合其中任何一条,那么跟着我一起从零开始,用FastAPI构建你的第一个高性能API,绝对是个不会后悔的选择。
2. 5分钟快速上手:创建你的第一个API
光说不练假把式,咱们直接动手。FastAPI的入门门槛低到令人发指,前提是你已经安装了Python 3.6以上的版本。我强烈建议你使用虚拟环境来管理项目依赖,这样可以避免包版本冲突。打开你的终端,跟着我一步步来。
首先,创建项目目录并安装必要的包。除了FastAPI本身,我们还需要一个ASGI服务器来运行它,生产环境推荐Uvicorn或Hypercorn,开发时用Uvicorn就行,因为它支持热重载。
# 创建项目文件夹并进入
mkdir fastapi-demo && cd fastapi-demo
# 创建虚拟环境(这里以venv为例)
python -m venv venv
# 激活虚拟环境
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# 安装FastAPI和Uvicorn
pip install fastapi uvicorn
安装完成后,创建一个名为 main.py 的文件,这就是我们应用的入口。打开它,输入以下代码:
from fastapi import FastAPI
# 创建FastAPI应用实例。这个`app`对象是整个应用的核心。
app = FastAPI()
# 使用装饰器定义一个GET请求的路由,路径是根目录"/"
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI!"}
# 再定义一个带路径参数的接口
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
# item_id被声明为int类型,FastAPI会自动进行类型验证和转换。
# q是一个可选的查询参数,类型是字符串,默认值为None。
return {"item_id": item_id, "q": q}
代码非常简洁,对吧?我们逐行看一下:第一行导入FastAPI类;第二行实例化一个应用对象;接着用 @app.get() 装饰器定义了两个路径操作函数。第一个函数响应根路径的GET请求,返回一个JSON。第二个函数演示了路径参数(item_id)和查询参数(q)的使用。这里有个关键点:我们使用了Python的类型提示(item_id: int)。这不仅仅是注释,FastAPI会利用它来自动进行请求数据的验证、序列化和生成API文档。
现在,让我们运行这个应用。在终端项目目录下执行:
uvicorn main:app --reload
命令解释一下:main 指的是 main.py 文件,app 指的是文件中创建的 app = FastAPI() 实例。--reload 参数让服务器在代码更改后自动重启,非常适合开发。
看到 Application startup complete 的提示后,打开浏览器,访问 http://127.0.0.1:8000。你会立刻看到 {"message": "Hello, FastAPI!"} 的JSON响应。更神奇的是,访问 http://127.0.0.1:8000/docs,你会看到一个完整的、可交互的API文档(Swagger UI)。你可以直接在这个页面上点击“Try it out”来测试 /items/{item_id} 接口,输入参数,查看实时响应。这种开发体验,用过就回不去了。
2.1 理解路径操作:GET, POST, PUT, DELETE
RESTful API的核心是对资源的不同操作,通过HTTP方法(GET, POST, PUT, DELETE等)来体现。FastAPI通过不同的装饰器来支持这些方法,直观明了。
让我们扩展一下 main.py,实现一个简单的待办事项(Todo)API的增删改查:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
app = FastAPI()
# 用一个内存中的列表模拟数据库
fake_todos_db = []
# 定义数据模型(Schema),使用Pydantic
class TodoItem(BaseModel):
title: str
description: Optional[str] = None
completed: bool = False
class TodoItemUpdate(BaseModel):
title: Optional[str] = None
description: Optional[str] = None
completed: Optional[bool] = None
# 1. 获取所有待办事项 (GET /todos/)
@app.get("/todos/", response_model=List[TodoItem])
async def read_todos():
return fake_todos_db
# 2. 创建新的待办事项 (POST /todos/)
@app.post("/todos/", response_model=TodoItem)
async def create_todo(todo: TodoItem):
fake_todos_db.append(todo)
return todo
# 3. 获取单个待办事项 (GET /todos/{item_id})
@app.get("/todos/{item_id}", response_model=TodoItem)
async def read_todo(item_id: int):
if item_id < 0 or item_id >= len(fake_todos_db):
raise HTTPException(status_code=404, detail="Todo item not found")
return fake_todos_db[item_id]
# 4. 更新待办事项 (PUT /todos/{item_id})
@app.put("/todos/{item_id}", response_model=TodoItem)
async def update_todo(item_id: int, todo_update: TodoItemUpdate):
if item_id < 0 or item_id >= len(fake_todos_db):
raise HTTPException(status_code=404, detail="Todo item not found")
stored_item = fake_todos_db[item_id]
# 只更新提供的字段
update_data = todo_update.dict(exclude_unset=True)
updated_item = stored_item.copy(update=update_data)
fake_todos_db[item_id] = updated_item
return updated_item
# 5. 删除待办事项 (DELETE /todos/{item_id})
@app.delete("/todos/{item_id}")
async def delete_todo(item_id: int):
if item_id < 0 or item_id >= len(fake_todos_db):
raise HTTPException(status_code=404, detail="Todo item not found")
fake_todos_db.pop(item_id)
return {"message": "Todo item deleted successfully"}
在这个例子中,我们完整演示了RESTful风格的基本操作。注意 response_model 参数,它声明了接口的响应模型,FastAPI会用这个模型来校验和序列化返回的数据,并体现在API文档中。HTTPException 用于抛出标准的HTTP错误。Pydantic模型 TodoItemUpdate 中所有字段都是可选的,这符合局部更新的语义。通过这个简单的例子,你已经掌握了FastAPI处理请求和响应的核心模式。
3. 深入请求与响应:玩转参数、模型与验证
掌握了基本操作后,我们来深入看看FastAPI如何处理各种复杂的输入和输出。这是它真正强大的地方,得益于Pydantic的深度集成。
3.1 路径参数、查询参数与请求体
这三者是



被折叠的 条评论
为什么被折叠?



