简体   繁体   English

处理 Flask RESTful 端点查询的正确方法是什么?

[英]What is the correct way to handle queries for a Flask RESTful endpoint?

I am creating an API using Flask-RESTful, and am attempting to make a resource that returns all items in a database that are like a user defined string.我正在使用 Flask-RESTful 创建一个 API,并试图创建一个资源来返回数据库中的所有项目,就像用户定义的字符串一样。

The endpoint for this resource is defined as:此资源的端点定义为:

api = Api(app)
api.add_resource(ItemsList, '/privateapi/item?query=<string:tag>')

And the resource itself is:资源本身是:

class ItemsList(Resource):

    def get(self, tag):
        search = f"%{tag}%"
        items = ItemModel.query.filter(ItemModel.item_name.like(search)).all()
        return {"items": [item.json() for item in items]}

The problem is that when I send a GET request to the endpoint http://127.0.0.1:5000/privateapi/item?query=appl I get a 404 response.问题是,当我向端点http://127.0.0.1:5000/privateapi/item?query=appl发送 GET 请求时,我收到了404响应。

When I change the endpoint to api.add_resource(ItemsList, '/privateapi/item/<string:tag>') and then query the API I get the desired response.当我将端点更改为api.add_resource(ItemsList, '/privateapi/item/<string:tag>')然后查询 API 时,我得到了所需的响应。

However, I would prefer to use the query approach since I am not trying to GET a single record but want to return an array.但是,我更愿意使用查询方法,因为我不是要获取单个记录而是要返回一个数组。 I just think it makes more sense this way.我只是认为这样更有意义。

What could I try?我可以尝试什么?

In flask, query parameters aren't used to match routes (only the path part of the URL is relevant).在 flask 中,不使用查询参数来匹配路由(仅 URL 的路径部分相关)。 When you write:当你写:

api.add_resource(ItemsList, '/privateapi/item?query=<string:tag>')

You have created a route that will never match (well, not exactly; see below).您创建了一条永远不会匹配的路线(好吧,不完全匹配;见下文)。

You access query parameters in the request.args value, like this:您访问request.args值中的查询参数,如下所示:

from flask import Flask, request
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)


class ItemsList(Resource):
    def get(self):
        query = request.args.get("query")
        return f"Query expression was: {query}"


api.add_resource(ItemsList, "/privateapi/item")

if __name__ == "__main__":
    app.run(debug=True)

With the above code, if I write:使用上面的代码,如果我写:

curl http://127.0.0.1:5000/privateapi/item?query=appl

I get as the response:我得到的回应是:

"Query expression was: appl"

When I said "You have created a route that will never match" this was actually a bit of lie.当我说“你创建了一条永远不会匹配的路由”时,这实际上是一个谎言。 In fact, you have created a route that requires a literal ?事实上,您已经创建了一条需要文字? in the URL path, so if you were to make a request for this URL:在 URL 路径中,所以如果您要为此 URL 发出请求:

curl http://127.0.0.1:5000/privateapi/item%3Fquery=appl

It would work, but it's not what you want.它会起作用,但这不是你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM