API设计痛点:为什么你的接口总是不够灵活?

31 阅读4分钟

API设计痛点:为什么你的接口总是不够灵活?

你是否曾遇到过这样的需求:需要让API接口能够根据不同的输入返回不同的结果?比如根据书籍ID获取特定书籍,或按类别筛选数据?

今天我们就来解决这个痛点,学习FastAPI中路径参数查询参数的使用技巧,让你的API从此变得 “灵活”、“聪明”起来。

路径参数

本小节,我们将讨论 FastAPI 中的路径参数。

什么是路径参数呢?

设想一下,有一个路径是:“/books/book_one”

路径参数就是URL中的动态部分,让我们能够通过URL定位特定资源。

从 “静态” 到 “动态”

静态路径:每次请求,总是返回所有书籍

@app.get("/books")
async def read_all_books():
    return BOOKS

动态路径:访问不同URL,将获得不同结果

@app.get("/books/{book_title}")
async def read_all_books(book_title: str):
    for book in BOOKS:
        if book.get('title').casefold() == book_title.casefold():
            return book
    return {"message": "Not Found"}

当访问到 http://127.0.0.1:8000/books/title%20one,将返回 《Title One》的详细信息。

当访问到 http://127.0.0.1:8000/books/title%20two,将返回 《Title Two》的详细信息。

注意:
在 URL 请求路径中,空格使用 `%20` 表示。因为,在 URL 请求路径中是不允许有空格出现的。

在上面例子中,当访问到 `http://127.0.0.1:8000/books/title%20two`时,意味着我们可以匹配的动态参数的值为 “title two”。

注意:动态路径是有顺序要求的。

# ✅ 正确顺序:先具体后通用
@app.get("/books/mybook")  # 静态路径在前
async def read_special_book():
    return {"book_title": "My Favorite Book"}

@app.get("/books/{book_title}")  # 动态路径在后
async def read_book(book_title: str):
    # 处理动态请求

如果上面的顺序颠倒,当用户访问 /books/mybook 时,请求会被动态路径捕获,导致页面无法访问。

查询参数

接下来,我们一起来讨论查询参数。

查询参数是什么呢?

查询参数是 URL 路径中?后面的部分,格式为参数名=值,多个参数用&连接。

下面代码,使用 “类别” 筛选书籍:

@app.get("/books/")
async def read_category_by_query(category: str):
    books_to_return = []
    for book in BOOKS:
        if book.get('category').casefold() == category.casefold():
            books_to_return.append(book)

    return books_to_return

当我们访问 http://127.0.0.1:8000/books/?category=science 时,返回结果如下:

[  {    "title": "Title One",    "author": "Author One",    "category": "science"  },  {    "title": "Title Two",    "author": "Author Two",    "category": "science"  }]

实战应用:路径参数 + 查询参数

在实际开发中,我们经常需要同时使用两种参数:

@app.get("/books/{book_author}/")
async def read_category_by_query(book_author: str, category: str):
    books_to_return = []
    for book in BOOKS:
        if (book.get('author').casefold() == book_author.casefold()
                and book.get('category').casefold() == category.casefold()):
            books_to_return.append(book)

    return books_to_return

当我们访问:http://127.0.0.1:8000/books/Author%20Two/?category=science 时,意味我们查询的是作者为 “Author Two”,且类别为 “science” 的所有书籍。

Swagger UI:自动生成的交互式文档

FastAPI 最强大的功能之一就是自动生成API文档。

  1. 启动服务后访问:http://127.0.0.1:8000/docs
  2. 可以看到所有API接口的可视化界面
  3. 直接在线测试接口,无需使用 Postman 等其他工具。

我们回到浏览器的 Swagger UI 中,并刷新页面。

image-20251224190339239

我们找到 GET /books/{book_title} 这个 API 接口,打开它,点击 “Try it out”,给到 “book_title” 参数一个值 Title One ,点击 Execute,执行这个请求。我们得到响应码和响应体如下:

image-20251224190252924

我们找到 GET /books/{book_author}/" 这个 API 接口,打开它,点击 “Try it out”,我们传递两个参数,一个给 “book_author” 传递 author two ,一个给 “category” 传递 science,点击 Execute,执行这个请求。我们得到的响应码和响应体如下:

image-20251213164229102

使用场景分析

路径参数使用场景:

  1. 获取特定资源(如根据 ID 获取用户信息)
  2. 层次结构数据(如/users/{user_id}/orders/{order_id}

查询参数使用场景:

  1. 筛选数据(如按日期、状态、类别过滤)
  2. 分页查询(如?page=1&size=20
  3. 排序(如?sort=name&order=desc

-------- 写在最后 --------

我的公众号正在连载《FastAPI 开发实战》、《Python 核心技术》、《Python 自动化办公》《职场》。

关注我,每天解锁一个实用知识点。


点赞 :如果觉得有收获,点赞支持一下吧!

分享 :分享给身边同样对Python感兴趣的朋友!

关注我 :不要错过每一篇 Python 实战内容!

每周更新 Python 核心技术、FastAPI 开发实战、Python 自动化办公、职场等硬核技巧,助你成为 10 倍效率的开发者!


#Python #FastAPI #API #Web开发 #程序员 #编程教程 #效率提升