Python 快速搭建 Web API:手把手带你用 FastAPI 搞定!

1,121 阅读9分钟

image.png


引言

大家好,我是程序员韩立!在现代 Web 开发中,前后端分离架构越来越流行,而 Web API (应用程序编程接口) 就是连接前端与后端的桥梁。它允许不同的应用程序或服务之间进行数据交换和功能调用。

你可能会想,搭建一个 API 是不是很复杂?其实,借助 Python 强大的生态,我们可以非常快速地构建出功能完善、性能出色的 Web API。

本文将手把手带你使用目前非常流行的高性能 Python Web 框架 FastAPI,快速搭建一个简单的 Web API。无论你是 Python 新手,还是想了解 API 开发的后端/前端工程师,相信这篇文章都能给你带来帮助!

读完本文,你将学会:

  • 什么是 Web API 及其基本概念。
  • 为什么选择 FastAPI?
  • 如何安装和配置 FastAPI 环境。
  • 创建你的第一个 API 端点 (Endpoint)。
  • 处理路径参数和查询参数。
  • 处理请求体 (Request Body) 数据 (如 POST 请求)。
  • 利用 FastAPI 自动生成的交互式文档。

准备好了吗?让我们开始吧!

什么是 Web API?

简单来说,Web API 是一组定义好的规则和协议,允许不同的软件系统通过 HTTP(S) 协议进行通信。最常见的 API 类型是 RESTful API,它使用标准的 HTTP 方法 (如 GET, POST, PUT, DELETE) 对资源进行操作。

例如,前端应用可以通过调用后端的 /api/users (GET 请求) 来获取用户列表,或者通过调用 /api/users (POST 请求,并附带用户信息) 来创建一个新用户。

为什么选择 FastAPI?

Python 有很多优秀的 Web 框架可以用来构建 API,比如 Flask、Django REST framework 等。那我们为什么推荐 FastAPI 呢?

  • 高性能:  FastAPI 基于 Starlette (用于性能) 和 Pydantic (用于数据验证),是目前性能最高的 Python 框架之一,可与 NodeJS 和 Go 相媲美。
  • 快速开发:  代码量少,开发效率高,直观易懂。
  • 类型提示:  大量使用 Python 的类型提示,减少运行时错误,提高代码健壮性,并能获得更好的编辑器支持 (如自动补全)。
  • 自动文档:  能自动生成交互式的 API 文档 (基于 OpenAPI 和 JSON Schema),如 Swagger UI 和 ReDoc,无需额外编写文档!
  • 易学易用:  官方文档清晰,学习曲线相对平缓。
  • 异步支持:  原生支持 async/await 语法,轻松处理高并发请求。

对于需要快速构建、高性能、自带文档的 API 项目来说,FastAPI 是一个绝佳的选择。

实战:一步步搭建你的第一个 API

第一步:环境准备

首先,确保你的电脑安装了 Python (建议 3.7+ 版本)。然后,创建一个项目目录,并设置一个虚拟环境 (这是一个好习惯,可以隔离项目依赖)。

bash复制代码
# 1. 创建项目文件夹
mkdir myfastapi_project
cd myfastapi_project

# 2. 创建虚拟环境 (Windows)
python -m venv venv
#    激活虚拟环境 (Windows CMD)
venv\Scripts\activate
#    激活虚拟环境 (Windows PowerShell)
#    (可能需要先执行 Set-ExecutionPolicy Unrestricted -Scope Process)
venv\Scripts\Activate.ps1
#    激活虚拟环境 (macOS/Linux)
source venv/bin/activate

# 3. (可选) 确认虚拟环境已激活 (命令行前面会出现 (venv) 字样)

第二步:安装 FastAPI 和 Uvicorn

在激活的虚拟环境中,使用 pip 安装 FastAPI 和 Uvicorn。Uvicorn 是一个 ASGI (异步服务器网关接口) 服务器,用来运行我们的 FastAPI 应用。

bash复制代码
pip install fastapi "uvicorn[standard]" pydantic
  • fastapi: 核心框架。
  • uvicorn[standard]: ASGI 服务器,[standard] 会带来一些额外的优化库。
  • pydantic: FastAPI 内部使用它进行数据验证和序列化,虽然 FastAPI 会自动安装,但显式安装有助于理解。

第三步:编写第一个 API 端点

在项目根目录下创建一个 main.py 文件,并写入以下代码:

python复制代码
# main.py
from fastapi import FastAPI

# 1. 创建 FastAPI 实例
app = FastAPI()

# 2. 定义一个 API 端点 (路径操作装饰器)
@app.get("/")  # 当有 GET 请求访问根路径 "/" 时,执行下面的函数
async def read_root():
    # 3. 返回 JSON 响应
    return {"message": "Hello, FastAPI World!"}

@app.get("/hello")
async def say_hello():
    return {"greeting": "你好,掘金的朋友们!"}

代码解释:

  1. 导入 FastAPI 类。
  2. 创建一个 FastAPI 应用实例 app
  3. 使用 @app.get("/") 装饰器将下面的 read_root 函数与根路径 / 的 GET 请求关联起来。FastAPI 支持异步函数 (async def),当然也支持普通函数 (def)。
  4. 函数返回一个 Python 字典,FastAPI 会自动将其转换为 JSON 响应。
  5. 我们还添加了另一个 /hello 路径。

第四步:运行 API 服务器

在终端 (确保虚拟环境已激活且在 main.py 所在的目录下),运行以下命令启动 Uvicorn 服务器:

bash复制代码
uvicorn main:app --reload
  • main: 指的是 main.py 文件。
  • app: 指的是在 main.py 中创建的 FastAPI 实例 app
  • --reload: 这个参数让服务器在代码更改后自动重启,非常适合开发环境。

你应该会看到类似以下的输出:

复制代码
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [xxxxx] using statreload
INFO:     Started server process [xxxxx]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

现在,打开你的浏览器,访问 http://127.0.0.1:8000,你会看到:

json复制代码
{"message":"Hello, FastAPI World!"}

访问 http://127.0.0.1:8000/hello,你会看到:

json复制代码
{"greeting":"你好,掘金的朋友们!"}

恭喜!你已经成功运行了你的第一个 Web API!

第五步:处理路径参数

有时,我们需要从 URL 路径中获取参数,比如获取特定 ID 的用户信息 /users/{user_id}

修改 main.py

python复制代码
from fastapi import FastAPI

app = FastAPI()

# 模拟一些数据
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]

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

@app.get("/hello")
async def say_hello():
    return {"greeting": "你好,掘金的朋友们!"}

# 新增:处理路径参数
@app.get("/items/{item_id}") # {item_id} 就是路径参数
async def read_item(item_id: int): # 使用类型提示 int,FastAPI 会做数据校验
    # 注意:实际应用中 item_id 通常是字符串,这里为了演示类型校验用 int
    # 如果 item_id 不能转为 int,FastAPI 会自动返回 422 错误
    if 0 <= item_id < len(fake_items_db):
         return fake_items_db[item_id]
    return {"error": "Item not found"}

重启服务器 (如果没用 --reload 的话需要手动重启)。现在访问 http://127.0.0.1:8000/items/1,你会得到:

json复制代码
{"item_name":"Bar"}

如果访问 http://127.0.0.1:8000/items/abc,由于 abc 不能转换为 int,你会收到 FastAPI 自动生成的错误响应 (HTTP 状态码 422 Unprocessable Entity)。这就是类型提示的好处!

第六步:处理查询参数

查询参数是 URL 中 ? 后面的键值对,常用于过滤、分页等,例如 /items?skip=0&limit=10

继续修改 main.py

python复制代码
from fastapi import FastAPI
from typing import Union # 导入 Union

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}, {"item_name": "Qux"}]

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

@app.get("/hello")
async def say_hello():
    return {"greeting": "你好,掘金的朋友们!"}

# 修改:处理查询参数
@app.get("/items/") # 注意路径是 /items/
async def read_items(skip: int = 0, limit: int = 10): # 定义查询参数 skip 和 limit,并给默认值
    return fake_items_db[skip : skip + limit]

@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None): # 添加可选查询参数 q
    # q: Union[str, None] = None 表示 q 是一个可选的字符串参数
    response = {}
    if 0 <= item_id < len(fake_items_db):
        response = fake_items_db[item_id]
        if q: # 如果用户提供了查询参数 q
            response.update({"q": q}) # 将 q 添加到响应中
        return response
    return {"error": "Item not found"}

现在你可以这样访问:

  • http://127.0.0.1:8000/items/ (使用默认值 skip=0limit=10)
  • http://127.0.0.1:8000/items/?skip=1&limit=2 (获取索引 1 和 2 的项)
  • http://127.0.0.1:8000/items/0?q=somequery (获取索引 0 的项,并传入查询参数 q)

第七步:处理请求体 (POST 请求)

通常,创建新资源或发送复杂数据时,我们会使用 POST 请求,并将数据放在请求体 (Request Body) 中,一般是 JSON 格式。FastAPI 使用 Pydantic 模型来定义和验证请求体数据。

修改 main.py

python复制代码
from fastapi import FastAPI
from pydantic import BaseModel # 导入 BaseModel
from typing import Union, List # 导入 List

# 1. 定义 Pydantic 数据模型 (用于请求体)
class Item(BaseModel):
    name: str
    description: Union[str, None] = None # 可选字段
    price: float
    is_offer: Union[bool, None] = None   # 可选字段

app = FastAPI()

# 为了简单起见,我们用一个列表来存储创建的 items
items_storage = []

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

# ... (之前的 GET 请求代码省略)

# 新增:处理 POST 请求和请求体
@app.post("/items/") # 使用 @app.post 装饰器
async def create_item(item: Item): # 将请求体声明为 Item 模型类型
    # FastAPI 会自动将请求的 JSON 数据解析、验证,并填充到 item 对象中
    # 如果数据格式不对或缺少必须字段,会自动返回 422 错误
    item_dict = item.dict() # 将 Pydantic 模型转为字典
    if item.is_offer:
        item_dict.update({"message": "This item has a special offer!"})
    items_storage.append(item_dict) # 简单地存入列表
    return item_dict

# 新增:获取所有创建的 items (用于验证 POST 是否成功)
@app.get("/created_items/", response_model=List[Item]) # 使用 response_model 限制响应格式
async def get_created_items():
    # 注意:这里为了演示 response_model,直接返回了列表
    # 实际项目中,存储的数据可能和 Pydantic 模型不完全一致,需要转换
    # 这里假设 items_storage 里存的就是符合 Item 模型的字典列表
    return items_storage

现在,你需要使用能发送 POST 请求的工具,比如 curl、Postman 或 Insomnia。

使用 curl 发送 POST 请求:

bash复制代码
curl -X POST "http://127.0.0.1:8000/items/" \
-H "Content-Type: application/json" \
-d '{
    "name": "New Awesome Item",
    "price": 99.9,
    "description": "This is a really cool item"
}'

服务器会返回:

json复制代码
{"name":"New Awesome Item","description":"This is a really cool item","price":99.9,"is_offer":null}

如果请求的 JSON 缺少 nameprice,或者 price 不是数字,FastAPI 会自动返回详细的 422 错误信息。

然后你可以访问 http://127.0.0.1:8000/created_items/ 来查看所有已创建的物品。

第八步:探索自动交互式文档

FastAPI 最酷的功能之一就是自动生成的 API 文档。在服务器运行的情况下,打开浏览器访问:

  • http://127.0.0.1:8000/docs

你会看到 Swagger UI 界面,它列出了你所有的 API 端点,并且可以直接在页面上进行交互式测试!

image.png

  • http://127.0.0.1:8000/redoc

你会看到 ReDoc 生成的替代文档界面,更加侧重于展示。

image.png

这一切都是基于你的代码和类型提示自动生成的,无需任何额外配置!

总结

恭喜你!通过本文的指引,你已经成功使用 Python 和 FastAPI 快速搭建起了一个包含 GET 和 POST 请求、能处理路径参数、查询参数和请求体的基本 Web API,并且了解了 FastAPI 自动生成文档的强大功能。

FastAPI 的简洁、高效和强大特性使其成为现代 Python Web API 开发的热门选择。当然,API 开发还涉及到数据库交互、用户认证、错误处理、部署等更多内容,但这已经为你打下了坚实的基础。

希望这篇文章能点燃你对 Python API 开发的兴趣!赶紧动手试试吧,用 FastAPI 构建你自己的下一个项目!


如果你觉得这篇文章对你有帮助,请不吝点赞👍、收藏✨和评论💬! 你的支持是我持续创作的最大动力!