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&bean
and 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.