[Fixed]-REST Api PUT method dispatch

1đź‘Ť

My understanding is that you want to perform some action on the article. If you want to do it in a purely REST way you should add some kind of transaction for each action you have. So something like this

POST /api/publish-article-transaction
{
   articleId: 2
}

-- Response

{
  publish_article_transaction: {
    id: 123,
    articleId: 2,
    status: ok
  }
}

The logic behind the ´POST´ is that you create a transaction object rather than modifying the article itself.

Here is a good answer to your question as well
REST actions and URL API design considerations

Another more general example would be

POST /api/article-transaction
{
  action: "publish",
  articleId: 2
}

0đź‘Ť

I think we can convert actions like activate, publish or share to resources(nouns) for RESTful urls.

Article Activation:

PUT /api/article-activation/<pk>/ # activate an article

DELETE /api/article-activation/<pk>/ # deactivate an article

Article Publishing:

PUT /api/article-publication/<pk>/ # publish an article

DELETE /api/article-publication/<pk>/ # unpublish an article

For reference: (Taken from the article link you mentioned in comments:)

What about actions that don’t fit into the world of CRUD operations?

This is where things can get fuzzy. There are a number of approaches:

1. Restructure the action to appear like a field of a resource. This
works if the action doesn’t take parameters. For example an activate
action could be mapped to a boolean activated field and updated via a
PATCH to the resource.

2. Treat it like a sub-resource with RESTful
principles. For example, GitHub’s API lets you star a gist with PUT /gists/:id/star and unstar with DELETE /gists/:id/star.

3. Sometimes you
really have no way to map the action to a sensible RESTful structure.
For example, a multi-resource search doesn’t really make sense to be
applied to a specific resource’s endpoint. In this case, /search would
make the most sense even though it isn’t a resource. This is OK – just
do what’s right from the perspective of the API consumer and make sure
it’s documented clearly to avoid confusion.

👤Rahul Gupta

0đź‘Ť

I did something similar, only a little bit differently, like

{"do": "activate"}

but it can also be done your way.

First, I created a method on model which did the job, def activate(), like setting attribute activated to true. Then in the partial_update method (it’s for PATCH, for put it’s update (or put, depending on which APIViews you are using)) I retrieved the value like this:

action = request.query_params.get('do')
if action == 'activate':
    something.activate()

in your case it would be a little bit more different because you just set a parameter “activated” to “true” or false, but you still need this line:

activated = request.query_params.get('activated')

Leave a comment