鉴于RESTful Web服务都基于“一切都被表示为资源并且可以通过地址(URI)访问”的神圣理念,这对于CRUD应用程序来说可能是有意义的(所有示例都是关于列表/创建/更新/删除实体)。但是,其他业务逻辑如何创建一个与CRUD操作无关的简单计算器RESTful服务呢? 什么是这样的REST服务的好设计?
其次,如果SOAP的逻辑已经完全合理,那么使用REST而不是SOAP的真正优势是什么呢?
答案 0 :(得分:32)
HTTP POST不一定要创建持久资源。在RFC 2616, section 9.5我们找到:
POST方法执行的操作可能不会产生资源 可以通过URI识别。在这种情况下,200(OK)或204 (No Content)是适当的响应状态,具体取决于是否 或不响应包括描述结果的实体。
这意味着我们可以考虑“创建计算”,而不必将计算结果保留在它自己的URL上。您的API可能如下所示:
Request:
POST /calculations
Content-Type: text/plain
3 + 3 / 12 ^ ( 3 * PI)
Response:
200 OK
Content-Type: text/plain
3.005454
这样做的好处是,您不会通过URL传递“内容”,当您尝试通过URL长度有限的客户端或代理提交长计算时,该内容将会中断。您还可以为请求和响应提供不同的表示形式。
答案 1 :(得分:17)
计算机服务很容易以RESTful方式建模。 “CRUD”中的“R”代表“读”,并且没有理由“读”也不能表示“计算”。因此,可以通过GET访问简单的Reverse Polish计算器服务:
GET https://calc.com/rpnCalc?3&4&%2B
7
上面的URI方案只是向GET请求添加了三个参数:
3
4
+ (URL-encoded as %2B)
这是一个幂等,安全且可缓存的请求。如果这是一个非常复杂的数学查询,花了很多分钟来计算,我可以将这些查询路由到开箱即用的HTTP代理,并使用它来立即返回任何预先计算的值,如果重复查询相同的URI。 / p>
根据您需要执行的计算类型,您还可以将非常复杂的查询POST到Calculator资源(将查询作为请求主体传递),并且服务器可能会将URI返回到“result”资源,然后你可以GET来检索结果,甚至可以通过它们进行分页。
其次,如果使用REST而不是SOAP的真正优势是什么? SOAP的逻辑已经完全有意义了吗?
我可以使用命令行工具(如curl)访问上述计算器服务,而无需构建复杂的SOAP。我可以在几秒钟内编写对它的调用,而无需使用任何第三方XML库或SOAP工具包。我可以使用HTTP代理等商品工具来缓存结果并提高性能。我不必担心SOAP互操作性或检查WS-I兼容性。如果我正确使用超链接,那么我可以在不影响现有客户端或让他们甚至重新编译的情况下改进和改进我的服务。没有WSDL版本,也没有我必须维护多年的脆弱合同。客户端已经知道GET / PUT / POST / DELETE做了什么,我没有必要重新定义或重新记录它们的语义。决定使用JSON而不是XML的API客户端可以使用HTTP的内置内容协商功能来获取它。我可以使用SOAP和Web服务完全零。
嘿,如果SOAP符合您的需求,请使用它。使用REST有很多好处,但它们可能不适合您的情况。至少,了解一下REST可以为你提供一本体面的书like this one,然后在获得完整的故事之后再想一想。
答案 2 :(得分:3)
这是REST中名词和动词之间紧张关系的一个很好的例子。使用“添加”或“加法器”作为资源的建议非常幼稚。这意味着每个操作都作为GET完成“加法器”或“减法器”。当然,人们可以将资源“计算”,然后我们使用动词。我们可以将它改为“计算器”或“答案”,这些都是名词,但我们确实没有做过任何有用的事情。
答案 3 :(得分:3)
这个问题已经有几年了。但似乎仍有一个让我和很多同事感到困惑的问题。我们无法达到满足每个人的解决方案。
但是对于一个简单的计算器,我认为下面的JAXRS实现提供了一个干净的API。
/**
* This class defines a CalculatorResource.
*/
@Path("v{version}/calculators/{id}")
@Named
public class CalculatorResource {
private final Long value;
public CalculatorResource() {
value = 0L;
}
public CalculatorResource(Long initialValue) {
this.value = initialValue;
}
@GET
public Long getValue() {
return value;
}
@Path("+{value}")
public CalculatorResource add(@PathParam("value") Long value) {
return new CalculatorResource(this.value + value);
}
@Path("-{value}")
public CalculatorResource subtract(@PathParam("value") Long value) {
return new CalculatorResource(this.value - value);
}
@Path("*{value}")
public CalculatorResource multiply(@PathParam("value") Long value) {
return new CalculatorResource(this.value * value);
}
}
通过这样的实现,URI可以是一个易于阅读的公式。
EG。 / API / V1 /计算器/ mycalc / + 9 / -4 / * 3 / + 10 将返回25。