作为一个例子,想象一个动态定价系统,您可以要求提供将盒子从一个地方移动到另一个地方的报价。由于在你提出要求之前价格并不存在,这并不像从数据库中检索数据那么简单,而是需要运行实际的搜索过程。
我经常在这种场景中看到的是一个基于请求/响应的端点:
POST /api/offers
{
"customerId" : "123",
"origin" : {"city" : "Amsterdam"},
"destination" : {"city" : "New York"},
"boxes": [{"weight" : 100},{"weight": "200"}]
}
201:
{
"id" : "offerId_123"
"product" : {
"id" : "product_abc",
"name": "box-moving"
}
"totalPrice" : 123.43
}
请求与响应无关,只是要求其中一个查找另一个的所有信息。
我解释";通过表示操纵资源";我认为这也适用于创作。在那之后,我想说,一个人应该创建搜索过程代替:
POST /api/offer-searches
{
"request" : {
"customerId" : "123",
"origin" : {"city" : "Amsterdam"},
"destination" : {"city" : "New York"},
"boxes": [{"weight" : 100},{"weight": "200"}]
}
}
201:
{
"id" : "offerSearch_123"
"request" : {
"customerId" : "123",
"origin" : {"city" : "Amsterdam"},
"destination" : {"city" : "New York"},
"boxes": [{"weight" : 100},{"weight": "200"}]
}
offers: [
"id" : "offerId_123"
"product" : {
"id" : "product_abc",
"name": "box-moving"
}
"totalPrice" : 123.43
]
}
在这里,请求和响应是同一个对象,在这个过程中,它通过结果得到了增强,但两者仍然是同一事物的表示,即搜索过程。
这样做的优点是;轨道";这个过程,通过识别它,以后可以再次读取。您仍然可以让/api/offers/offerId_123
返回创建的报价,而不必经历搜索资源的混乱。但它也有相当的权衡:复杂性。
现在我的问题是,这是第一个更像RPC的方法,我们甚至可以称之为REST吗?或者为了遵守REST约束,应该使用第二种方法吗?
现在我的问题是,这是第一种更像RPC的方法,我们甚至可以称之为REST吗?或者为了遵守REST约束,应该使用第二种方法吗?
这种方法与我们在网上做事的方式相比如何?
在大多数情况下,向服务器发送信息是使用HTML表单实现的。所以我们正在处理很多看起来像的请求
POST /efc913bf-ac21-4bf4-8080-467ca8e3e656
Content-Type: application/x-www-form-urlencoded
a=b&c=d
然后响应看起来像
201 Created
Location: /a2596478-624f-4775-a490-09edb551a929
Content-Location: /a2596478-624f-4775-a490-09edb551a929
Content-Type: text/html
<html>....</html>
换句话说,(a(资源的表示不是发送到服务器的信息,而是服务器根据发送的信息计算出的内容,(b(不一定与请求的有效负载具有相同的模式,这是完全正常的。。。甚至不一定是相同的媒体类型。
在贫血的文档存储中,您更有可能使用PUT或PATCH。PATCH请求通常在请求体中有一个补丁文档,因此您希望表示形式有所不同(比如application/json-PATCH+json(。但是,即使在PUT的情况下,服务器也可以在创建其资源时对表示进行更改(以使其与自己的约束一致(。
当然,当你处理包含";动作";,或者错误的表示,那么响应可能再次与请求完全不同。
TL;DR REST不在乎出价的表示是否"是";匹配";RFP的代表。
无论如何,您可能认为这是一个好主意,但它不必满足REST的约束或HTTP的语义。