最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

rest - Should I have double HTTP Patches? - Stack Overflow

programmeradmin3浏览0评论

I'm coding a simple todo list app in Flask for study. My todo model has title, description and a check attribute. When false is a "to do" task, and when the user click on a checkbox it will change to "true", so that task was done. That said, my current PATCH route can handle the title, description and check change, all in one.

So now I was thinking: in my frontend, I'll create the checkbox and when it's clicked the client will send a PATCH request with just the check value; for description and title, I'll create a "edit", so the user can edit those two and when its done he can click in a "save" button, when its clicked the client will send a PATCH request with title and/or description changes.

I realized that there's no way to a request with changes on all the three (title, description and check) could be made, check will be always working alone.

This is my PATCH code:

@app.route("/todo/update/<id>", methods=["PATCH"])
def update_todo(id):
    updated_todo = db.session.execute(db.select(Todo).filter_by(id=id)).scalar_one()
    if "check" in request.json:
        updated_todo.check = request.json["check"]
    if "title" in request.json:
        updated_todo.title = request.json["title"]
    if "description" in request.json:
        updated_todo.description = request.json["description"]

    db.sessionmit()
    return "", 204

Since I'm using if to know what's changing, could I create a new PATCH route just for check and let it work alone? Since I don't need to verify if check is in a title/description PATCH request (it never will be anyway), it'll be a little faster in theory, right? Is there any conceptual or convention problem around it?

It would be something like this:

@app.route("/todo/update/<id>", methods=["PATCH"])
def update_todo(id):
    updated_todo = db.session.execute(db.select(Todo).filter_by(id=id)).scalar_one()
    if "title" in request.json:
        updated_todo.title = request.json["title"]
    if "description" in request.json:
        updated_todo.description = request.json["description"]

    db.sessionmit()
    return "", 204

@app.route("/todo/update/check/<id>", methods=["PATCH"])
def update_todo(id):
    updated_todo = db.session.execute(db.select(Todo).filter_by(id=id)).scalar_one()
    updated_todo.check = request.json["check"]

    db.sessionmit()
    return "", 204

I'm coding a simple todo list app in Flask for study. My todo model has title, description and a check attribute. When false is a "to do" task, and when the user click on a checkbox it will change to "true", so that task was done. That said, my current PATCH route can handle the title, description and check change, all in one.

So now I was thinking: in my frontend, I'll create the checkbox and when it's clicked the client will send a PATCH request with just the check value; for description and title, I'll create a "edit", so the user can edit those two and when its done he can click in a "save" button, when its clicked the client will send a PATCH request with title and/or description changes.

I realized that there's no way to a request with changes on all the three (title, description and check) could be made, check will be always working alone.

This is my PATCH code:

@app.route("/todo/update/<id>", methods=["PATCH"])
def update_todo(id):
    updated_todo = db.session.execute(db.select(Todo).filter_by(id=id)).scalar_one()
    if "check" in request.json:
        updated_todo.check = request.json["check"]
    if "title" in request.json:
        updated_todo.title = request.json["title"]
    if "description" in request.json:
        updated_todo.description = request.json["description"]

    db.sessionmit()
    return "", 204

Since I'm using if to know what's changing, could I create a new PATCH route just for check and let it work alone? Since I don't need to verify if check is in a title/description PATCH request (it never will be anyway), it'll be a little faster in theory, right? Is there any conceptual or convention problem around it?

It would be something like this:

@app.route("/todo/update/<id>", methods=["PATCH"])
def update_todo(id):
    updated_todo = db.session.execute(db.select(Todo).filter_by(id=id)).scalar_one()
    if "title" in request.json:
        updated_todo.title = request.json["title"]
    if "description" in request.json:
        updated_todo.description = request.json["description"]

    db.sessionmit()
    return "", 204

@app.route("/todo/update/check/<id>", methods=["PATCH"])
def update_todo(id):
    updated_todo = db.session.execute(db.select(Todo).filter_by(id=id)).scalar_one()
    updated_todo.check = request.json["check"]

    db.sessionmit()
    return "", 204

Share Improve this question edited Mar 14 at 21:54 jonrsharpe 122k30 gold badges268 silver badges476 bronze badges asked Mar 14 at 21:47 Isaac AlfredoIsaac Alfredo 1
Add a comment  | 

1 Answer 1

Reset to default 0

Is there any conceptual or convention problem around it?

Yes; specifically, you seem to be confused about the meaning of "target resource"

PATCH /todo/update/check/1

What this request means is: apply the patch-document enclosed in this request to the /todo/update/check/1 resource. And given your description, that doesn't seem to be what you want the method to do.

The target URI of a PATCH request, like that of a PUT request or a DELETE request, should be the same URI that you use to GET the representation of the resource.

A typical remote authoring flow would look like

GET /example
# make local changes to the data returned
# create a patch document describing those changes
PATCH /example

Now, your resource model can be anything you want, and edits to the server's copy of a resource can also modify other resource (though you may not always be able to communicate that).

So you could be trying to do something like

GET /todo/1
# Follow the "edit the check" link
GET /todo/update/check/1
# Make your local changes to that
# Create your patch document
PATCH /todo/update/check/1

With a response like

200 OK
Content-Location: /todo/1

# Updated todo representation goes here

"The rules" as it were, might make more sense if you were to see what the standards have to say about cache-invalidation


Also, I see sometimes urls with a /create in the end in POST routes, is it wrong too, right? (like "/todo/create")

You can use any spelling conventions you like for your resource identifiers; that's part of the point. For example, this URL "just works"

https://www.merriam-webster/dictionary/create

How do you tell the web server you want to read a copy of this page?

GET /dictionary/create

How do you tell the web server to replace it's copy of the page with the request body?

PUT /dictionary/create

How do you tell the web server to update it's copy of the page using the patch document attached to the request?

PATCH /dictionary/create

How do you tell the web server to stop serving this web page?

DELETE /dictionary/create

If you design your interactions this way, then all general purpose web components will understand what's going on, and will be able to do useful things (in particular, a cache that has already stored the successful response of a GET request will know to get rid of it when it sees that PUT/PATCH/DELETE was successful).

发布评论

评论列表(0)

  1. 暂无评论