如何使用 FastAPI 从请求中 return 多个值?

How to return multiple values from a request using FastAPI?

我正在尝试使用 FastAPI + MongoDB 创建一个 API,它可以 return 来自请求的多个值。 MongoDB 充满了数据,使用 mongoengine 我可以在向特定端点发送请求时查询一个或所有数据。 我现在要做的是从端点接收一个或多个数据,例如:

在查询端点 http://127.0.0.1:8000/rice 时,我收到一个 JSON 响应,其中包含 MongoDB 上此项的所有数据。但问题是我需要让此端点咨询来自 MongoDB 和 return 的一个或多个数据,与用户发送到端点的数据一样多,例如:http://127.0.0.1:8000/rice&pasta&bean 和 return JSON 以及 MongoDB 中关于 ricepastabean 的信息。

在代码中,我有一个 main.py,其中的路线如下:

@app.get('/{description}', status_code=200)
def get_description(description):
    return JSONResponse(TabelaService().get_description(description))

此函数调用另一个函数,该函数调用另一个函数,该函数使用 queryset 查询来自 MongoDB 的数据并将其序列化:

    def get_description(self, description):
        try:
            description = TabelaNutricional.get_by_description(description)
            return self.serialize(description)
        except:
            raise DescriptionNotFound

下面是从MongoDB获取数据的函数:

    @queryset_manager
    def get_by_description(doc_cls, queryset, description):
        nutriente = queryset(description=str(description)).get()
        return nutriente

有人知道如何在端点中获取更多数据吗? 谢谢!

您可以声明类型为 List 的查询参数并显式使用 Query,如 this and answer, and as explained in the documentation 中所示。这样,您可以为查询参数接收多个值,例如,

http://127.0.0.1:8000/?item=rice&item=pasta&item=bean 

在服务器端,您可以遍历项目列表并为列表中的每个项目调用您的函数,并创建一个包含结果的字典以发送回客户端。例如:

@app.get('/', status_code=200)
def get_description(item: List[str] = Query(...)):
    data = {}
    for i in item:
        d = TabelaService().get_description(i)
        data[i] = d
        
    return JSONResponse(data)

如果您仍想使用 Path parameter,您可以使用下面的内容并按照您的问题中所示调用它,即 http://127.0.0.1:8000/rice&pasta&bean:

@app.get('/{items}', status_code=200)
def get_description(items: str):
    items = items.split('&')
    data = {}
    for i in items:
        d = TabelaService().get_description(i)
        data[i] = d
        
    return JSONResponse(data)

注意: 如果您使用上述方法(使用路径参数),http://127.0.0.1:8000/docs 处的 OpenAPI 文档 (Swagger UI) 将不会加载.这是因为在访问 URL 时,会调用上面的端点,并将 docs 作为 items 路径参数的值。因此,您可以在该端点上添加一个额外的路径,例如 @app.get('/api/{items}' 并使用 http://127.0.0.1:8000/api/rice&pasta&bean 调用它(因此,允许 /docs 成功加载),或者使用使用 Query 参数的第一种方法。