REST服务中的建模操作

时间:2013-06-21 23:11:41

标签: rest

我知道之前已经提出过这类问题。我有我的问题的解决方案,我想知道我是否在任何地方破坏REST或HTTP主体。

在我的系统中,我有一个名为member的资源,它支持通常的GET/POST/PUT操作。会员的状态为ActiveDisabled。我需要模拟禁用用户的操作。我理解为什么以下从REST角度来看是一个坏主意

POST api/member/john.smith/disable

我已经阅读了一个解决方案来接受代表禁用成员请求的资源,如下所示

public class DisableMemberRequest
{
    public string Username {get; set;}
}

然后在资源上方POST

POST api/DisableMemberRequest

虽然这种方法听起来很合理,但我认为这在干净的API接口方面是不对的。上述请求的响应应该是200 OK还是201 Created还是202 Accepted,这一点值得商榷。

我在想,我会创建一个名为DisabledMember的新资源,此资源上的PUT意味着应该禁用特定成员,如下所示

PUT api/disabledmember/john.smith

从REST / HTTP角度来看,这看起来是一个非常有效的设计。但我不是专家,并希望与那些长期坚持这样做的人一起验证这一点。

修改

我在与此页面上的其他程序员交互后添加这些详细信息。禁用该成员的过程不仅仅是关于在该成员上设置状态标志。禁用成员时,还需要触发其他工作流。

5 个答案:

答案 0 :(得分:4)

我喜欢这样做的一种方法是定义一个代表一组禁用成员的资源。要禁用成员,请将该成员添加到已禁用的成员集。它可能看起来像这样。

POST /api/DisabledMembers
Content-Type: text/uri-list

http://example.org/api/members/john.smith

如果要撤消操作,可以执行

POST /api/ActiveMembers
Content-Type: text/uri-list

http://example.org/api/members/john.smith

这种方法的好处是,做GET /api/DisabledMembers将是一件非常自然的事情。此外,通过使用text/uri-list,可以轻松地同时禁用/重新激活一组成员。

答案 1 :(得分:3)

你的前两个建议都有点味道,因为它们在URL中有一个动词。良好的RESTful架构仅定义类似名词的资源,因为HTTP协议定义了适用于这些资源的动词集。

另一个建议很有意思,但是PUT建议你可以执行GET来获得你刚放在那里的东西的代表,这在这里没有多大意义上下文。

根据您的说法,启用或停用用户帐户的过程非常重要,并且您不熟悉PUTPATCH操作只需“翻转”价值从truefalse。如果这需要一些时间,具有瞬态,并且很可能是您希望能够向API消费者公开以使他们了解该过程,那么将过程本身定义为一种资源是有意义的:

开始停用:

POST api/members/deactivations

获取已停用的当前状态或报告已发生的活动:

GET api/members/deactivations/john.smith

取消正在停用的停用(可选):

DELETE api/members/deactivations/john.smith

如果您可以重新启动帐户,则可能会采用类似的模式。

如果您觉得这些工作流程没有足够的实质可以证明它们是自己的资源,或者您只是不知道应该对GET做出什么反应,那么它表明工作流程不是非常重要,它不能简单地从API用户隐藏,并作为更改用户的active值的副作用触发。

答案 2 :(得分:1)

here中回答了类似的问题。

思考或应用REST作为起点的实用方法(至少对我有用)是以下列方式思考:

1)仅使用HTTP“GET / POST / PUT / DELETE”作为建模域名“行动”的方式。就像处理数据库时一样,所有操作都映射到CURD

2)URI / URL仅用于标识资源。不应该在URI中有任何“操作”。

3)交换的数据应该在HTTP消息的正文中。 只是为了简化讨论,而不是如何对数据本身进行建模

Tragedian的解决方案看起来很干净。

更新以解决@Suhas的评论

REST与命名约定无关。在设计REST API时,关键是如何考虑资源而不是“动作”。应始终将“Nonce”视为URL / URI中的资源。您已经拥有域操作应映射到的所有CURD操作,并操纵URL中的资源。

我喜欢Tragedian的解决方案,仅仅为了讨论,我们可以使用类似的nonce和不同的URL模式重构Tragedian的解决方案,以“更好地”适应不同的域使用。以下可能不是域的最佳解决方案,但它们等效于RESTful。

删除会员资格

  • DELETE api / membership / [member-id] /

获取会员资格

  • 获取api / membership / [member-id] / status /

添加会员资格

  • POST api / membership / [member-id] /

更新以解决“DisabledMember”作为资源的问题

如果使用“PUT DisabledMember”按照Suhas的建议做“禁用会员” 那么'DisabledMember'资源上的以下操作意味着什么呢?

DELETE DisabledMember→再次激活它?

POST DisabledMember - > ??

GET DisabledMember - 这是一个简单的☺

通过这种设计,它实际上“伪装”了资源中的“禁用”动作。 你可能仍然可以强迫它做你想做的事情,但它不会像我一样宁静。

答案 3 :(得分:0)

  

会员的状态为“有效”和“已停用”

因此,状态是成员实体/资源的属性;在这种情况下,为什么你不想在状态设置为Disabled的成员资源上使用简单的PUT方法?

答案 4 :(得分:0)

如果禁用用户的过程很短,为什么不使用HTTP PATCH?

See this answer to a similar question