我为我的架构的数据访问层(DAL)构建了一个RESTful服务:
POST http://example.com/data/User
GET|PUT|DELETE http://example.com/data/User/{UserId}
但是,对于业务逻辑层(BLL),使用了第二个非RESTful服务:
POST http://example.com/accountapi/register
POST http://example.com/accountapi/login
这个BLL服务不是直接调用DAL服务,而是直接与数据库对话。
您将如何改进此架构?
答案 0 :(得分:8)
回答主要问题。不,不是真的。回答次要问题。以上都不是。
基于REST的体系结构不适合标准的3层模型。三层模型的简单视图如下所示:
表示层< - >商业 逻辑层< - >数据层
考虑一下将表示层分成两部分,
渲染图层< - >用户界面 内容< - > BLL< - > DAL
如果您考虑使用常规Web应用程序,浏览器会获取HTML,CSS和Javascript内容,并在浏览器中以可视方式呈现它们。它是REST约束适用的用户界面内容层。如果您考虑超媒体约束,这是最明显的。 REST接口意味着就像用户界面一样导航。 REST接口返回重新表示的资源。
REST接口应返回与用户界面显示方式无关的用户界面内容。
REST客户端< - > REST接口< - > BLL< - > DAL
在我看来,REST客户端有两种形式,非常薄的媒体类型呈现引擎(例如Web浏览器)或屏幕抓取器(蜘蛛,mashup)。我松散地使用术语“屏幕抓取器”,因为如果您明智地选择媒体类型,那么客户端从您的用户界面内容中删除数据应该是微不足道的。
将业务逻辑层公开为REST接口的任何尝试通常都会产生一些影响。开发人员最终会询问如何在REST中进行事务处理。它们最终在客户端和BLL接口之间创建了大量的耦合,因为需要公开语义丰富的表示。他们忘记了所有关于超媒体约束的事情,因为大部分链接信息在业务逻辑层中不可用。他们开始抱怨HTTP和基于文本的内容类型的性能开销。
答案 1 :(得分:6)
(1)避免让您的(非REST)Web服务业务逻辑层对数据访问层进行进一步(RESTful)HTTP请求。当然这样做比直接方法调用效率低。但更重要的是,它需要您将BLL Web服务和DAL Web服务部署到单独的Web服务器实例(或单独的集群)上。否则,您可能会遇到所有您的HTTP工作线程忙于尝试提供BLL响应的情况,并且每个都被阻塞等待无效的HTTP工作线程为DAL响应提供服务。这可能导致停顿(如果执行超时/重试处理)或彻底死锁(如果不这样做)。
(2和3)如果您的Web服务客户端需要业务逻辑和数据访问,请将它们作为一组统一的服务提供。在内部,它们都依赖于相同的数据访问层方法调用:只是面向数据的Web服务实现只进行一次数据访问层调用,而面向业务逻辑的Web服务实现可以进行许多DAL调用。你绝对想要在Web服务层下单独构建BLL和DAL层。
我喜欢将Web服务视为面向“用户”的表示层的一部分,而这些用户恰好是其他程序。
答案 2 :(得分:3)
如果这是同一个应用程序,那么您应该让BLL层直接在代码中调用DAL层,而不是再次使用服务调用。这将使其保持更高的性能,同时保持代码的基本目的(高凝聚力)。
可能是这样。您的服务通常应该是执行业务功能的课程粒度组件。将用户保存在数据库中不是业务功能,而是一种特定的实现。 Register函数将该概念抽象为业务功能。然后,BLL层可以强制执行密码强度,密码加密,用户名唯一性等与数据访问无直接关系的内容。
可能不是。见#2。