如何在RESTful服务设计中正确支持记录的部分创建?
我正在设计一个restful服务来支持一个现有的向导,该向导允许用户提交一个新的资源(我们称之为如何在RESTful服务设计中正确支持记录的部分创建?,rest,restapi,Rest,Restapi,我正在设计一个restful服务来支持一个现有的向导,该向导允许用户提交一个新的资源(我们称之为customer),但它是分块提交的 此向导在用户提交每个页面时对其进行验证,但仅对用户提交的页面进行验证。只有当用户选择提交客户进行最终处理时,它才会对整个对象进行完全验证 为了简化向导,并允许我们在添加更多字段时在维护版本中随意移动UI,我们没有将向导的结构编码到资源中。客户不会按照向导显示数据的方式“汇总” 设计RESTful服务时,资源的命名子文档不一定在该资源的完整文档中按层次显示(或者至少
customer
),但它是分块提交的
此向导在用户提交每个页面时对其进行验证,但仅对用户提交的页面进行验证。只有当用户选择提交客户进行最终处理时,它才会对整个对象进行完全验证
为了简化向导,并允许我们在添加更多字段时在维护版本中随意移动UI,我们没有将向导的结构编码到资源中。客户不会按照向导显示数据的方式“汇总”
设计RESTful服务时,资源的命名子文档不一定在该资源的完整文档中按层次显示(或者至少不以相同的方式显示),这是否奇怪
假设我的向导页面是:
- 联系方式
- 食物偏好
- 恐惧清单
// Note that the wizard page groupings don't show up explicitly
{
customer: {
firstName: "Pilsner",
lastName: "Dopplebock",
emailAddress: "nextguest@hotelcalifornia.com",
addressLine1: "123 Fleece Place",
addressLine2: ""
town: "Ibinjad",
region: "North Dakota",
postalCode: "12123",
homePhoneNumber: "2123234124",
faxPhoneNumber: null,
meatPreference: "well-done",
allergies: "shellfish",
fears: [
"banshees",
"baths",
"sleeveless shirts"
]
}
}
假设资源的基本URL为:
http://www.somewhere.com/customers
http://www.somewhere.com/customers/{id}
创建以下restful URL/方法是奇怪的还是错误的,即使customer
实际上并没有按照它们所暗示的方式进行细分
http://www.somewhere.com/customers/contactinformation (POST)
http://www.somewhere.com/customers/{id}/contactinformation (POST, or PUT for update? maybe GET)
http://www.somewhere.com/customers/{id}/foodpreference (POST, or PUT for update?, maybe GET)
http://www.somewhere.com/customers/{id}/fears (POST to add a single item?, maybe PUT for a batch?, maybe GET)
我曾考虑过,如果我一次没有完整的资源,可以使用另一个向导URL,但在我看来,这似乎不适合资源导向:
http://www.somewhere.com/customerwizard/submitcontactinformation (POST)
http://www.somewhere.com/customerwizard/{customer-id}/submitcontactinformation
http://www.somewhere.com/customerwizard/{customer-id}/submitfoodpreference
http://www.somewhere.com/customerwizard/{customer-id}/fears
(可能是第二个问题,尽管相关):对于不一定显示在主集合上的集合样式资源,有一个count
子属性是否奇怪?我想这样做是为了支持分页视图
http://www.somewhere.com/customers/count (GET)
我不认为这个问题是引用的问题的重复。您并不是要求对现有资源执行部分更新,而是要求服务器验证“部分”资源(我认为这些资源本身就是整个资源,而不是您稍后通常向用户展示的资源) 在这种情况下,REST不一定是正确的选择。REST旨在优化静态或半静态资源的读访问,这些资源由潜在的分布式受众多次访问。为了提供帮助,您能否回答以下问题:
有一个很棒的资源,它可能有助于确定REST是否真的是您希望在API设计中遵循的路径选择替代设计是一种权衡。根据每种设计各自的优点和缺点做出明智的决定。URL就像
/customers/{id}/contactinformation
等等并不奇怪。您可能想问自己的一个问题是,在写入时将客户实体拆分为单独的片段是否有意义,并不意味着它们在读取时可以更好地单独提供服务。这肯定会使任何HTTP缓存更合理。例如,如果要获取实体片段,然后获取父实体,后续对片段的PUT只会使片段无效,父实体随后可能会提供过时的数据。更简单的方法是获取较小的父实体(它具有指向每个实体片段的链接)然后获取每个片段,在这种情况下,对片段的放置会正确地提示后续的GET检索新的副本。与Nicholas Shanks相比,我认为类似向导的系统符合REST背后的思想。在Web上看到这样的交互概念并不少见,也就是说,通常应用于签出页面上e页面输入客户信息,下一页输入送货地址,第三页输入付款数据,然后是确认页面,确认页面将触发实际订单
Jim Webber指出,在REST体系结构中,您主要实现一个域应用程序协议(如果您愿意,客户机将通过一个状态机)当客户端通过链接或类似于HTML表单的表单表示方式获得服务器提供的所有信息时,他们会跟进
因此,REST体系结构中的上述结帐系统可能如下所示:将项目放入购物篮后,服务器会向您提供附加链接,这些链接用一些链接关系(伪HAL表示)进行注释:
{
...,
“_链接”:{
“自我”:{
“href”:”https://..."
},
“创建表单”:{
“href”:”https://shop.acme.com/checkout-wizard-p1"
},
"https://acme.com/rel/checkout": {
“href”:”https://shop.acme.com/checkout-wizard-p1"
},
...
}
}
URI本身与此无关,因为URI的拼写在REST体系结构中并不重要,只要它符合中概述的规则即可。它也可能以UUID而不是checkout wiza结束