有点困惑,这是可以理解的,因为我已经看到大型公司设计其REST API的所有方式,如何正确使用REST。
您认为REST是资源收集系统是正确的。它代表代表性状态转移。如果问我,这不是一个很好的定义。但是主要概念是4个HTTP VERB,它们是无状态的。
需要注意的重要一点是,您只有4个带REST的VERBS。这些是GET,POST,PUT和DELETE。您的resend
示例将向REST添加新动词。这应该是一个危险信号。
问题1
重要的是要认识到REST API的调用者不必知道PUT
对集合执行会导致生成电子邮件。这对我来说有点泄漏。他们所知道的是,执行a PUT
可能会导致额外的任务,他们以后可以查询。他们将通过GET
对最近创建的资源执行来知道这一点。这GET
将返回资源以及Task
与之关联的所有资源ID。然后,您以后可以查询这些任务以确定它们的状态,甚至可以提交新的任务Task
。
您有几种选择。
REST-基于任务资源的方法
创建一个tasks
资源,您可以在其中将特定任务提交到系统中以执行操作。然后GET
,您可以根据ID
返回的任务确定其状态。
或者,您可以混合使用SOAP over HTTP
Web Service以便向体系结构中添加一些RPC。
查询特定资源的所有任务
GET http://server/api/myCollection/123/tasks
{ "tasks" :
[ { "22333" : "http://server/api/tasks/223333" } ]
}
任务资源示例
PUT http://server/api/tasks
{
"type" : "send-email" ,
"parameters" :
{
"collection-type" : "foo" ,
"collection-id" : "123"
}
}
==>返回任务的ID
223334
GET http://server/api/tasks/223334
{
"status" : "complete" ,
"date" : "whenever"
}
REST-使用POST触发动作
您始终可以将POST
其他数据添加到资源。我认为这将违反REST的精神,但仍会合规。
您可以执行类似以下的POST:
POST http://server/api/collection/123
{ "action" : "send-email" }
您将使用其他数据更新集合中的资源123。这些额外的数据实际上是告诉后端发送该资源电子邮件的操作。
我的问题是GET
资源上的a 将返回此更新的数据。但是,这可以解决您的需求,并且仍然是RESTful。
SOAP-接受从REST获得的资源的Web服务
创建一个新的WebService,您可以在其中基于REST API中的先前资源ID发送电子邮件。我不会在此详细讨论SOAP,因为最初的问题是关于REST的,因此不应将这两个概念/技术进行比较,因为它们是Apples和Oranges。
问题2
您在这里也有一些选择:
似乎许多发布REST API的大公司都公开了一个search
集合,这实际上只是一种传递查询参数以返回资源的方式。
GET http://server/api/search?q="type = myCollection & someField >= someval"
它将返回完全合格的REST资源的集合,例如:
{
"results" :
{ [
"location" : "http://server/api/myCollection/1",
"location" : "http://server/api/myCollection/9",
"location" : "http://server/api/myCollection/56"
]
}
}
或者,您可以允许像MVEL这样的查询参数。
问题3
我更喜欢这些子级别,而不是必须回去使用查询参数来查询其他资源。我不认为一种方法会一成不变。您可以同时实现这两种方式,并允许调用者根据他们首次进入系统的方式来决定哪种更为合适。
笔记
我不同意其他人的可读性评论。尽管有人可能会认为REST仍不供人类使用。用于机器消耗。如果我想查看自己的推文,请使用Twitter的常规网站。我不使用其API执行REST GET。如果我想以编程方式对自己的推文进行操作,则可以使用其REST API。是的,API应该是可以理解的,但是您gte
还不错,只是不直观。
REST的另一个主要优点是,您应该能够在API中的任意给定位置开始并导航至所有其他关联的资源,而无需提前知道其他资源的确切URL。GET
REST中VERB 的结果应返回其引用的资源的完整REST URL。因此,查询Person
将返回完全合格的URL(例如),而不是返回对象ID的查询http://server/api/people/13
。这样,即使URL更改了,您也可以始终以编程方式导航结果。
回应评论
实际上,在现实世界中,有些事情需要发生,而不是创建,读取,更新或删除(CRUD)资源。
可以对资源采取其他措施。典型的关系数据库支持存储过程的概念。这些是可以对一组数据执行的附加命令。REST本质上没有这个概念。而且没有理由应该这样做。这些类型的操作非常适合RPC或SOAP Web服务。
这是我在使用REST API时遇到的一般问题。开发人员不喜欢围绕REST的概念限制,因此他们将其调整为可以执行自己想要的任何事情。但这使它脱离了RESTful服务。从本质上讲,这些URL成为GET
对类似伪REST的servlet的调用。
您有几种选择:
- 创建任务资源
- 支持将
POST
其他数据添加到资源以执行操作。
- 通过SOAP Web服务添加其他命令。
如果您使用查询参数,将使用哪个HTTP VERB重新发送电子邮件?
GET
-这会重新发送电子邮件并返回资源的数据吗?如果系统缓存了该URL并将其视为该资源的唯一URL,该怎么办。每次他们访问URL时,都会重新发送电子邮件。
POST
-您实际上并没有向资源发送任何新数据,只是向附加查询参数发送了数据。
根据所有给定的要求,POST
对带有action field
as POST数据的资源执行会解决此问题。