想象一下某种银行应用程序,其中有一个用于创建帐户的屏幕。每个帐户都有货币和银行作为财产,货币是一个单独的类,以及银行即可。代码可能如下所示:
public class Account
{
public Currency Currency { get; set; }
public Bank Bank { get; set; }
}
public class Currency
{
public string Code { get; set; }
public string Name { get; set; }
}
public class Bank
{
public string Name { get; set; }
public string Country { get; set; }
}
根据REST设计原则,应用程序中的每个资源都应该有自己的服务,每个服务都应该有很好地映射到HTTP谓词的方法。因此,在我们的案例中,我们有 AccountService , CurrencyService 和 BankService 。
在创建帐户的屏幕中,我们有一些用户界面可以从银行列表中选择银行,并从货币列表中选择货币。想象一下,它是一个Web应用程序,这些列表是下拉列表。这意味着从CurrencyService填充一个下拉列表,从BankService填充一个下拉列表。这意味着当我们打开创建帐户的屏幕时,我们需要对两个不同的服务进行两次服务调用。如果该屏幕本身不在页面上,则可能会有来自同一页面的更多服务调用,从而影响性能。在这样的应用中这是正常的吗?如果没有,怎么可以避免?如何在不离开REST的情况下修改设计?
答案 0 :(得分:2)
这是正常的,无法避免...... ...除非您创建一个特定服务,在一次运行中返回特定屏幕的所有数据。
这是REST方法的一个负面因素 - 基本上如果你处理对象查询,并且你需要x对象的列表,那么你有x个调用。点。
这意味着REST设计在该级别上具有有限的可扩展性。
同样,在开始时 - 您始终可以使用特定服务在一次调用中返回复杂表单上所需的所有数据。
答案 1 :(得分:2)
这是一个架构决策,您应该根据系统的大小和复杂性。您的系统越大/越复杂,它就越可能从增加的分离/封装水平中受益(例如,您可能会发现BankService需要比CurrencyService更积极地扩展,并且单独运行这些服务将允许您这样做)。
但是,我在回答您的问题时会指出,您应该考虑缓存这些服务调用的结果并重用结果,而不是每次重新调用服务页面加载。如果(如名称所示),CurrencyService和BankService的结果不太可能经常更改,您可以一次缓存它们几分钟或几小时,而不必重复进行这些调用。
如果您的应用程序正忙(也就是说,如果您考虑的是每秒点击数而不是每小时点击次数)那么这可以在运行时节省您的内存,因为单个服务调用的结果是在多个页面请求(而不是每个页面需要单独获取结果集)。
答案 2 :(得分:1)
坚持,ReST就是代表资源。
我认为你不应该对以下内容过于严格:
根据REST设计原则,应用程序中的每个资源都应该有自己的服务,每个服务都应该有很好地映射到HTTP谓词的方法。
您在浏览器中表示的资源是“表单”并包含所有相关信息,这应该是完全正常的。
在定义URL结构时,请考虑正确的抽象程度。
答案 3 :(得分:0)
Slavo,
不需要为不同的资源提供不同的服务。一般而言,您应该只提供帮助您的客户实现目标的视图。如果其中一个观点是一个综合的“大”观点(资源),包括所有的银行和货币,那么这很好。您仍然可以为创建和编辑银行和货币提供细粒度的视图(资源)。
如果银行和货币恰好由不同的Web应用程序提供,并且您需要客户端来解析引用,那么请记住,HTML页面始终使用内嵌图像执行此操作。在这种情况下,缓存可以减少网络呼叫的数量(并且银行和货币列表似乎不会非常不稳定)。
(见http://www.nordsc.com/blog/?p=152)
示例:
GET /service/account-management
200 Ok
Content-Type: application/vnd.my.accounting
<page>
...
<banklist href="http://other.org/service/banklist" type="application/atom+xml" />
<currencylist href="http://standard.org/currencies" type="application/rss+xml" />
...
</page>
对银行列表和货币列表的子请求应该在大多数时间从客户端的私有缓存中提供。
扬