我们将要创建一些RESTful服务,这些服务本质上将成为一些基于SOAP的Web服务的传统。 SOAP服务更通用,将在整个组织中使用(至少是计划)。 RESTful服务专为特定客户量身定制。这个决定已经做出,不幸的是我无法改变......
我们正在努力解决如何以一种有意义的方式构建RESTful资源,遵循REST最佳实践,并调用这些SOAP服务而不会让自己太多痛苦。
我们对后端服务的粒度级别有一些自由,但普遍的共识是:保持粗略的粒度,不要根据特定客户的需求定制它们。
这导致了一些有趣的问题。例如,如何处理父母的子资源。我们一直在使用的典型示例是:具有子地址的客户。
我们有一个后端SOAP服务,它将客户更新为整个实体。但是,REST服务客户端可能只需要更新帐单地址。我们如何最好地处理子资源的后续更新?
我们应该在“父级”(客户)处进行更新,还是公开一个更细粒度的REST操作,将该地址视为资源并以这种方式更新?后者似乎是正确的,RESTful方式。但是,如果我们这样做,我们基本上只会为一个更新调用粗粒度的后端服务。似乎没有意义,因为它是一个非常重量级的电话。
我们还在努力解决如何将RESTful资源与我们的后端域模型相关联的问题。我们可能将RESTful资源视为单个实体,但在后端的域中,它可能是许多不同的实体。我们现在有一个相对简单的数据库表来处理这个问题,但是当我们将越来越多的资源映射到域对象时,我不相信它会扩展。
这些只是我们遇到的事情的几个例子......我想知道是否有人遇到过类似的问题,并且有任何建议或者可能能够指出我可能有的一些文章一些最佳实践。
似乎这不是一个不寻常的问题,并且随着越来越多的应用程序使用RESTful架构而变得更加相关,但我似乎无法在其上找到任何其他信息。
非常感谢!
答案 0 :(得分:6)
我发现我建模的大多数域很容易映射到REST。最重要的事情是进入正确的心态。 REST将域建模为一组资源,其中SOAP倾向于强调一组操作。另一种看待这种情况的方法是REST关注状态转换的状态和SOAP。更简单的是,您可以将REST视为名词而不是SOAP作为动词。我知道这不是一个完美的类比,但它对我有用。
当你进入这种状态时,映射应该几乎是自动的。我们来看看您的客户地址互动。
我认为更新整个客户只是为了更新地址,但不熟悉您的域名,这可能不合适。如果要与地址专门交互,只需创建子资源(或嵌套资源)。您最终会得到以下url和动词的映射:
GET /customer/72/address # return the address of customer with id 72
PUT /customer/72/address # update the address of customer with id 72
在这种特殊情况下,映射删除,创建或列出操作可能没有意义。
如果您的客户拥有某个实体的集合,让我们说小部件,您可以映射这样的交互:
GET /customer/72/widgets # return the widgets of customer with id 72
POST /customer/72/widgets # create a new widget for customer with id 72
GET /customer/72/widgets/158 # return widget with id 158 of customer 72
PUT /customer/72/widgets/158 # update widget with id 158 of customer 72
DELETE /customer/72/widgets/158 # delete widget with id 158 of customer 72
只要有正确的心态,请记住,映射不是一对一的,你会没事的。
答案 1 :(得分:5)
不要尝试将域实体建模为资源。将您的视图/用例建模为资源。为特定客户构建资源绝对没有错。 REST鼓励偶然重复使用,即意外重用,它并不建议您尝试构建适用于所有可能场景的资源。
RESTful框架应该使资源真正便宜且快速创建。如果您需要五种不同的资源来模拟客户访问的所有方式,那就没问题。
总的来说,我更喜欢使用粗粒度资源,因为这是HTTP优化的。