如何设计REST API来处理非CRUD操作?


11

我正在尝试将一组基于SOAP的服务转换为RESTful API。

我首先通过分析操作名称来识别资源,然后获得了资源Subscription

当我需要更新订阅的状态时,不能直接向POST服务器发送请求,因为我没有直接访问资源的权限,但是我需要调用一些RPC样式的操作来更新其属性。此外,仅且仅当我将订阅状态更改为“活动”时,才需要对外部服务的附加调用。

在这些情况下,处理基础操作的最佳实践是什么?

我想出的解决方案是使用查询参数,这样,如果我需要调用激活服务,则可以使用以下方法:

POST /subscriptions/{subscriptionid}/?activate=true

考虑到我不能直接更新我的订阅对象字段,是否有最佳实践来处理这种转换?

更新1:

我可以在POST请求的正文中放入一些值,例如“ state”:“ active”

并检查我的服务中要触发的正确操作。


REST的命令到HTTP动词的映射因复杂的操作而失败。您最好只进行RPC样式的调用POST activateSubscription / {id},不会有人对此感到困惑
Ewan 2016年

@Ewan我不确定这是否符合RESTful模型,但我想出了另一种解决方案:在我的代码中,我可以根据输入有效负载调用适当的RPC样式的操作(我可以在主体中传递state = active。我的发帖请求,该代码将调用激活码)
Vektor88 '16

1
对这样的现有资源的更新应该是PATCH,然后查询的主体就是要更改内容的部分模型。POST应该是创建资源的请求。除了使用户更清楚之外,这种区别还将使您的代码更容易知道发生此操作的时间,而不是资源发布。
Cochese先生16年

1
@ Vektor88通常,但这是幂等操作,您需要在其中传递整个资源状态表示形式。这个用例似乎更像是部分更新,非常适合PATCH。
Cochese先生16年

1
@MrCochese POST不是幂等的。
JimmyJames

Answers:


8

您需要观看Jim Webber的演讲

当我需要更新订阅的状态时,不能直接向服务器发送POST请求,因为我没有直接访问资源的权限,而是需要调用一些RPC样式的操作来更新其属性。此外,仅且仅当我将订阅状态更改为“活动”时,才需要对外部服务的附加调用。

认为“消息传递”;向您的域发送一条消息,描述您想要发生的事情。消息的副作用是您的域模型实际上会更改其状态。“资源”是消息队列。

POST /subscriptions/{subscriptionid}/?activate=true

资源名称的拼写与机器无关紧要;但是当您使用的标识符违反资源是“名词”的约定时,人们会变得很挑剔。

另外,我们所讨论的是从属于的资源/subscriptions/{subscriptionid},因此约定(请参阅RFC 3986)要求使用路径段来表达这种关系,而不是使用查询部分。

所以这些拼写可能是合理的

POST /subscriptions/{subscriptionid}/messages
POST /subscriptions/{subscriptionid}/activations

1
吉姆·韦伯(Jim Webber)的演讲可在youtube.com/watch?v=aQVSzMV8DWc上找到
user674669 '18

0

如果它是用于激活/停用内容的布尔值标志,那么我想说默认是使用JSON:

POST /subscriptions/{subscriptionid}/
{
    format: 0,
    subscription: 
    {
        active: false
    }
}

如果要支持更多属性,可以轻松扩展它。另一种方法是给它自己的端点:

POST /subscriptions/{subscriptionid}/active/
DELETE /subscriptions/{subscriptionid}/active/

就个人而言,只有active在此事件的状态需要/具有可在JSON中传递/获取的属性(例如用户ID或设置)时,我才使用此属性。

如果它不是布尔值,而只是一个您需要触发但不需要/没有任何状态反馈的操作(立即200 OK除外),我将像这样使用一个端点来触发它,就像RPC:

POST /subscriptions/{subscriptionid}/activate/

如有疑问,请阅读以下内容:http : //www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful(请参阅“那些不适合CRUD操作的操作呢? ”)


0

REST无法正常运行。Activate是动词,不能是状态,Active是状态。

由于RESTful无法正常工作,因此您无法告诉RESTful服务该怎么做,但是可以为服务队列添加工作。

看到这个:

PUT /subscriptionQueue
subscriptionId={subscriptionId}
active=true

此请求是RESTful的,并支持RESTful的所有优点(例如性能,酸性...)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.