Home > Software design >  How to return multiple values from a request using FastAPI?
How to return multiple values from a request using FastAPI?

Time:05-01

I'm trying to create an API using FastAPI MongoDB that can return multiple values from the request. The MongoDB is full of data and using mongoengine I can consult one or all data when sending a request to the specific endpoint. What I'm trying to do now is receive one or more data from an endpoint, for example:

When consulting the endpoint http://127.0.0.1:8000/rice I get a JSON response with all the data from this item that is on MongoDB. But the problem is that I need to have this endpoint consulting one or more data from MongoDB and return as much data as the user sends to the endpoint, for example: http://127.0.0.1:8000/rice&pasta&beanand return the JSON with the information that it is in the MongoDB about rice, pasta and bean.

In the code I have a main.py with the routes like:

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

This function calls another function that call another function that use queryset to consult the data from MongoDB and serialize it:

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

And bellow is the function who get the data from MongoDB:

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

Does anyone has a clue to how to get more data in the endpoint? Thank you!

CodePudding user response:

You can declare a query parameter with a type of List and explicitly use Query, as demonstrated in this and this answer, and as explained in the documentation. In this way, you can receive multiple values for the query parameter, e.g.,

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

On server side, you can loop through the list of items and call your function for each item in the list, and create a dictionary with the results to send back to the client. For instance:

@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)

If you still want to use a Path parameter instead, you can use the below and call it as shown in your question i.e., 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)

Note: If you use the above (with the path parameter), the OpenAPI docs (Swagger UI) at http://127.0.0.1:8000/docs won't load. That's because when accessing that URL, the endpoint above is called, and takes docs as the value for the items path parameter. Thus, you can either add an extra path on that endpoint, e.g., @app.get('/api/{items}' and call that using, for instance, http://127.0.0.1:8000/api/rice&pasta&bean (thus, allowing /docs to load successfully), or use the first approach with the Query parameter.

  • Related