引言:为什么选择FastAPI?
在现代软件开发中,API(应用程序编程接口)无处不在。它是连接不同服务、不同应用的桥梁。你想做的几乎任何事——从获取天气数据,到让AI模型进行推理,再到将数据存入数据库——通常都是通过调用一个API来完成的。
那么,如果你想用Python来创建一个API呢?
在过去,开发者可能会选择Flask或Django。但近年来,一个名为FastAPI的新星迅速崛起,并成为许多开发者的首选。原因何在?
- Fast (快速): 它的性能极高,与Node.js和Go等语言的框架不相上下。这得益于它底层的Starlette(用于Web部分)和Pydantic(用于数据部分)。
- Easy (易用): 框架学习曲线平缓,代码量少,非常直观。
- 自动文档: 这是FastAPI最令人惊艳的特性之一。你只需编写API代码,它就能自动为你生成两种交互式的API文档界面(Swagger UI 和 Redoc)。你不再需要手动编写和维护API文档!
- 智能校验: 基于Python的类型提示,FastAPI(通过Pydantic)能自动对接收到的数据进行校验和转换,确保你的API收到的都是格式正确的数据。
环境准备
要运行FastAPI,你需要两样东西:
- FastAPI库本身。
- 一个ASGI服务器,用来运行你的应用,比如
uvicorn
。
# 安装FastAPI和uvicorn
pip install fastapi "uvicorn[standard]"
你的第一个API
让我们创建一个最简单的API。新建一个名为main.py
的文件:
# main.py
from fastapi import FastAPI
# 1. 创建一个FastAPI实例
app = FastAPI()
# 2. 定义一个“路径操作” (Path Operation)
@app.get("/")
def read_root():
return {"message": "你好, FastAPI!"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
代码解读:
app = FastAPI()
: 创建了一个应用实例。@app.get("/")
: 这是一个“装饰器”,它告诉FastAPI,下面这个函数负责处理发往路径/
的GET
请求。@app.get("/items/{item_id}")
: 定义了另一个路径。这里的{item_id}
是路径参数,意味着你可以访问像/items/5
这样的URL。item_id: int
: FastAPI利用Python的类型提示,自动将URL中的item_id
(此时是字符串"5")转换并校验为整数。如果访问/items/foo
,它会自动返回一个清晰的错误。q: str | None = None
: 这是一个查询参数。你可以访问/items/5?q=somequery
。因为它被声明为可选的(None
),所以如果URL中不提供q
,也不会报错。
运行你的API服务器
在main.py
文件所在的目录下,打开终端,运行:
uvicorn main:app --reload
main
: 指的是main.py
文件。app
: 指的是我们在代码中创建的app = FastAPI()
对象。--reload
: 这个标志非常有用,它让服务器在你的代码文件被修改后自动重启。
服务器启动后,你会看到类似这样的输出:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
见证奇迹:自动交互式文档
现在,打开你的浏览器,做两件事:
-
访问
http://127.0.0.1:8000/docs
你会看到一个Swagger UI界面。这是一个交互式的API文档。它列出了你所有的API端点(我们刚才定义的/
和/items/{item_id}
),你可以直接在页面上对它们进行测试! -
访问
http://127.0.0.1:8000/redoc
你会看到另一种风格的文档界面 Redoc。
这个特性是革命性的。你只需要专注于编写业务逻辑,文档就自动生成了,并且永远和你的代码保持同步。
使用Pydantic进行数据校验
FastAPI的超能力很大程度上来自于Pydantic
库。你可以用它来定义复杂的数据结构,FastAPI会用它来做请求体(Request Body)的校验。
假设我们想创建一个POST
请求来接收一个物品的数据。
修改main.py
:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
def create_item(item: Item):
return {"item_name": item.name, "price_with_tax": item.price + (item.tax or 0)}
# ... 保留之前的 .get 请求 ...
代码解读:
- 我们从
pydantic
导入BaseModel
并创建了一个Item
类。 - 这个类定义了我们期望从请求中收到的JSON对象的“形状”:必须有一个字符串
name
,一个浮点数price
,以及两个可选的字段。 - 在
create_item
函数中,我们把参数item
的类型声明为我们刚创建的Item
模型。
现在,FastAPI会自动:
- 从POST请求中读取JSON请求体。
- 校验它是否符合
Item
模型的结构。- 如果
name
缺失或不是字符串,price
不是数字,它会自动返回一个指明具体错误的422 Unprocessable Entity响应。
- 如果
- 如果数据有效,它会将JSON转换为一个
Item
对象,你可以在函数中直接使用item.name
这样的方式来访问数据。
你可以再次访问/docs
,会发现新的POST /items/
端点已经出现。你甚至可以直接在文档里构建一个JSON来测试它。
总结
你刚刚已经用Python构建了一个健壮、高性能、自带文档的现代API。
- 你学会了使用
@app.get
,@app.post
等装饰器定义API路径。 - 你理解了路径参数和查询参数的区别。
- 你掌握了使用Pydantic模型来定义和校验请求数据的强大功能。
- 你体验了
uvicorn
如何运行你的应用,以及--reload
带来的便利。
FastAPI让创建高质量的Web API变得前所未有的简单和愉快。在你的下一个需要提供接口的项目中,给FastAPI一个机会吧!
...