『FastAPI』快速掌握“请求与响应”的基础用法

点赞 + 关注 + 收藏 = 学会了

本文简介

上一讲介绍了 FastAPI 的基础用法,这一讲我们聊聊 FastAPI 常用的请求方法、获取前端传过来的数据以及返回数据给前端。

常见的请求方法

现在流行 RESTfulAPI 设计规范,RESTful 是基于 REST(Representational State Transfer )架构风格的 Web 服务设计原则。REST 将一切事物视为资源,每个资源由 URI(Uniform Resource Identifier,统一资源标识符)进行唯一标识。

RESTful API 通过标准的 HTTP 方法与资源进行交互,通常包括以下常见方法:

  • GET:从服务器读取资源(查询资源)。
  • POST:在服务器创建资源(通常用于添加新资源)。
  • PUT:在服务器更新资源(通常用于替换或更新现有资源)。
  • DELETE:从服务器删除资源。
  • PATCH:部分更新资源。

FastAPI 当然也支持这几种请求方法啦,而且写起来非常简单。

简单来说,一行「装饰器」写明路由、请求参数,下面跟着一个「方法」来处理这个路由的请求。

python 复制代码
from fastapi import FastAPI # 引入FastAPI

app = FastAPI() # 注册 app

@app.请求方法("路径")
def xxx():

先用不带参数的方法演示一下。

python 复制代码
from fastapi import FastAPI # 引入FastAPI

app = FastAPI() # 注册 app

# get方法
@app.get("/demo")
def demoGet():
    return {"msg": "这是GET"}

# post方法
@app.post("/demo")
def demoPost():
    return {"msg": "这是POST"}

# put方法
@app.put("/demo")
def demoPut():
    return {"msg": "这是PUT"}

# patch方法
@app.patch("/demo")
def demoPatch():
    return {"msg": "这是PATCH"}

# delete方法
@app.delete("/demo")
def demoDelete():
    return {"msg": "这是DELETE"}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run('main:app', host="127.0.0.1", port=8000, reload=True, workers=1)

上面的代码很简单,我通过 @app.xxx 写了5个接口,这些接口对应的路由地址都是 /demo,只不过他们的请求方法不一样。

最后一段代码 uvicorn.run('main:app', host="127.0.0.1", port=8000, reload=True, workers=1) 的作用是通过 uvicorn 启动一个本地服务,地址是 127.0.0.1,端口是 8000,而且你的代码发生变化后它也会自动给你重启服务器。

此时使用 Postman (你用其他工具也行)请求一下 http://127.0.0.1:8000/demo 可以看到对应的返回内容。

比如用 PATCH 方法请求:

是不是很简单~

日常工作中,尤其是中小公司其实没那么遵守 RESTful 规范,大多数时候都是用 GETPOST。接下来我主要用这两个方法讲解接下来的内容,其他方法的用法其实也是一样的。

获取请求参数

客户端像服务器发起请求,通常会带一些参数。

如果是 GET 请求,通常会在 URL 上带「路径参数」和「查询参数」。

POST 请求除了「路径参数」和「查询参数」外,还有「请求头」信息也能获取到,还可以通过「请求体」把数据传给后端。

路径参数

「路径参数」是在 URL 中定义的一部分,通常用于标识某个特定的资源,例如我的掘金个人页面的地址是 https://juejin.cn/user/2673620576140030。每个人都可以通过 https://juejin.cn/user 访问用户首页,但要在这个 URL 后面拼一个用户 id2673620576140030 就是我掘金账号的 id

如果我们要实现这种请求,可以这么做。

python 复制代码
@app.get("/demo/{userId}")
def demoGet(userId: int):
    return {
        "msg": "这是GET",
        "userId": f"这是用户ID:{userId}"
    }

在路由部分定义了一个 int 型的路径参数 userid ,当你访问 /demo/123 时,userid 的值为 123。并且会作为函数参数传递到 demoGet 函数中。

还可以定义多个路径参数

python 复制代码
@app.get("/demo/{userId}/{orderId}")
def demoGet(userId: int, orderId: int):
    return {
        "msg": "这是GET",
        "userId": f"这是用户ID:{userId}",
        "orderId": orderId
    }

查询参数

「查询参数」是 URL 中 ? 之后的一部分,通常用在过滤、分页、排序等查询操作(当然,这些操作你也可以照样写在路径参数或者请求体里)。

「查询参数」与「路径参数」不同,「路径参数」是 URL 的一部分,而「查询参数」则在 URL 路径后添加,用于指定可选的附加数据。

查询参数的特点

  • 非必需:查询参数通常用于提供可选信息,因此在许多情况下它们是可选的。
  • 灵活性:可以使用多个查询参数进行数据过滤、分页、排序等操作。
  • 键值对 :查询参数的形式是 key=value,如:?search=keyword&limit=10
  • 顺序不重要:多个查询参数之间的顺序不影响请求结果。

举个例子,创建一个查询博客列表的接口。

python 复制代码
@app.get("/blogList")
def getBlogList(limit: int = 10, page: int = 1, search: str = None):
    return {
      "limit": limit,
      "page": page,
      "search": search
    }

在这个例子中,limitpage 参数具有默认值,而 search 参数是可选的,没有指定默认值,因此默认为 None

此时访问 http://127.0.0.1:8000/blogList?limit=20&page=1&search=FastAPI 就会进入 getBlogList,会将这些参数返回给客户端。

需要注意的是,「查询参数」的参数不需要在装饰器里定义,直接写在函数参数里即可。

请求头参数

「请求头」是 HTTP 请求中的元数据,用于传递有关请求的附加信息。

比如客户端的类型、身份验证信息、内容类型等。它们位于 HTTP 请求的顶部,通常包含键值对形式的数据。

常见的请求头字段包括:

  • Authorization: 用于身份验证,例如 Bearer Token。
  • Content-Type: 指示请求体的数据类型,如 application/json
  • User-Agent: 标识客户端应用或浏览器的信息。
  • Accept: 指定客户端可接受的数据格式,如 application/json

举个例子

python 复制代码
from fastapi import FastAPI, Header
from typing import Optional

app = FastAPI()

@app.get("/headers/")
def getHeaders(user_agent: Optional[str] = Header(None), content_type: Optional[str] = Header(None)):
    return {
        "User-Agent": user_agent,
        "Content-Type": content_type
    }

在这个例子中

  • Header(None):告诉 FastAPI,这个请求头是可选的。如果客户端没有传递该请求头,值会是 None

  • user_agent: Optional[str]:获取请求中的 User-Agent 头,它表示客户端(例如浏览器或移动设备)的详细信息。

  • content_type: Optional[str]:获取请求中的 Content-Type 头,它表示请求体的媒体类型(如 application/json)。

获取请求头的所有信息

如果你需要获取请求的所有请求头,可以通过 request.headers 来获取。

python 复制代码
from fastapi import FastAPI, Request

app = FastAPI()

@app.get("/headers")
def getHeaders(request: Request):
    headers = request.headers
    return dict(headers)

此时在浏览器访问 http://127.0.0.1:8000/headers 就会展示以下信息。

请求体数据

POST 请求通常用于向服务器发送数据(例如表单数据或 JSON 数据),这些数据会被放置在请求体中。

FastAPI 通过 Pydantic 模型或请求体字段来提取和验证这些数据。我们可以指定请求体中的参数,并控制它们是否为必填项。

先看看怎么写。

python 复制代码
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str
    price: float
    tax: float = 0.0  # 设置默认值为 0.0

@app.post("/items/")
async def createItem(item: Item):
    return {
        "name": item.name,
        "description": item.description,
        "price": item.price,
        "tax": item.tax
    }

使用 Pydantic 模型来定义请求体的数据结构。Pydantic 会自动验证传入的数据,并确保其符合指定的类型和规则。通过这种方式,可以确保参数的必填性和数据格式。

上面这个例子定义了一个 Item 类,这个类定义了一个包含四个字段的请求体:

  • name: 必填,字符串类型。
  • description: 必填,字符串类型。
  • price: 必填,浮点数类型。
  • tax: 可选,浮点数类型,默认值为 0.0

此时通过 Postman 向 http://127.0.0.1:8000/items 发起一个 POST 请求,在 Body 里传入以下数据。

json 复制代码
{
  "name": "雷猴之书",
  "description": "这是一本教你如何打招呼的书",
  "price": 29.99
}

以上就是本文的全部内容,相信你已经能用 FastAPI 写出各种请求方法的接口了。

但如果把所有接口都写在同一个文件中,接口多了就不好维护了。

下一讲介绍「路由分发」解决这个问题。

pi

点赞 + 关注 + 收藏 = 学会了

相关推荐
大鲤余2 分钟前
rust 中if let、match -》 options和Result枚举类型
开发语言·后端·rust
墨城烟柳Q5 分钟前
自动化爬虫-selenium模块万字详解
爬虫·python·selenium·自动化
raoxiaoya7 分钟前
python安装selenium,geckodriver,chromedriver
开发语言·python·selenium
Dxy12393102161 小时前
python使用requests发送请求ssl错误
开发语言·python·ssl
gxchai1 小时前
利用pythonstudio写的PDF、图片批量水印生成器,可同时为不同读者生成多组水印
python
ao_lang1 小时前
剑指offer第五天
python·算法·cpp
codeGoogle1 小时前
计算机书籍打包
前端·后端·编程语言
哎呦没1 小时前
健身行业创新:SpringBoot管理系统应用
java·spring boot·后端
这个男人是小帅1 小时前
【GCN】 代码详解 (1) 如何运行【pytorch】可运行版本
人工智能·pytorch·python·深度学习·分类
方才coding1 小时前
2024最新的开源博客系统:vue3.x+SpringBoot 3.x 前后端分离
spring boot·后端·开源·博客系统·前后端分离·个人博客·vue 3.x