[英]REST Api PUT method dispatch
According to REST design guidelines it is better to map state changing actions like activate
, publish
, share
to PUT methods body as fields. 根据REST设计指南 ,最好将状态更改操作(例如activate
, publish
, share
映射为PUT方法主体作为字段。
Like that: 像那样:
PUT /api/articles/32
{
"activated": true
}
My question is how to dispatch in put method handler in the backend which action is which. 我的问题是如何在后端的put方法处理程序中调度哪个动作是哪个。 How do i know if it is "activated" or it is "shared"? 我怎么知道它是“激活的”还是“共享的”? Any suggestions? 有什么建议么?
@detail_route(methods=['PUT'])
def put(self, request, *args, **kwargs):
# if action == 'activate'
# activate()
# if action == 'publish'
# publish()
return Response(status=status.HTTP_200_OK)
My understanding is that you want to perform some action on the article
. 我的理解是您想对article
执行一些操作。 If you want to do it in a purely REST way you should add some kind of transaction for each action you have. 如果要以纯REST方式执行此操作,则应为您执行的每个操作添加某种事务。 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. “ POST”背后的逻辑是您创建事务对象,而不是修改商品本身。
Here is a good answer to your question as well REST actions and URL API design considerations 这是对您的问题以及REST操作和URL API设计注意事项的一个很好的答案
Another more general example would be 另一个更一般的例子是
POST /api/article-transaction
{
action: "publish",
articleId: 2
}
I think we can convert actions like activate
, publish
or share
to resources(nouns) for RESTful urls. 我认为我们可以将诸如activate
, publish
或share
操作转换为RESTful URL的资源(名词)。
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? 那些不适合CRUD操作的操作又如何呢?
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. 1.重新构造动作,使其看起来像资源的字段。 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. 例如,激活动作可以映射到布尔激活字段,并通过PATCH更新到资源。
2. Treat it like a sub-resource with RESTful principles. 2.使用RESTful原则将其视为子资源。 For example, GitHub's API lets you star a gist with
PUT /gists/:id/star
and unstar withDELETE /gists/:id/star
. 例如,GitHub的API允许您使用PUT /gists/:id/star
标记主意,而使用DELETE /gists/:id/star
。3. Sometimes you really have no way to map the action to a sensible RESTful structure. 3.有时,您确实无法将操作映射到合理的RESTful结构。 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. 在这种情况下,/ search即使不是资源,也将是最有意义的。 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. 没关系-只需从API使用者的角度进行正确的操作,并确保已对其进行了清晰记录,以免造成混淆。
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. 首先,我在完成此任务的模型上创建了一个方法def activate()
,例如将attribute设置为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: 然后在partial_update方法(用于PATCH,用于更新(或放置,取决于您使用的APIViews))中,我检索了以下值:
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”设置为“ true”或“ false”,但仍然需要以下行:
activated = request.query_params.get('activated')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.