简体   繁体   English

REST Api PUT方法分派

[英]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设计指南 ,最好将状态更改操作(例如activatepublishshare映射为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. 我认为我们可以将诸如activatepublishshare操作转换为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 with DELETE /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.

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