我为我的架构的数据访问层(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服务,而是直接与数据库对话.
你会如何改进这种架构?
BLL服务应该调用DAL服务吗?
我应该放弃DAL服务并仅公开BLL服务吗?
我应该以某种方式在我的RESTful DAL服务上注入业务逻辑吗?如果有,怎么样?
Darrel Mille.. 9
回答主要问题.不,不是真的.回答次要问题.以上都不是.
基于REST的体系结构不适合标准的3层模型.三层模型的简单视图如下所示:
表示层< - >业务逻辑层< - >数据层
考虑一下将表示层分成两部分,
渲染层< - >用户界面内容< - > BLL < - > DAL
如果您考虑常规Web应用程序,浏览器将获取HTML,CSS和Javascript内容,并在浏览器中以可视方式呈现它们.它是REST约束适用的用户界面内容层.如果您考虑超媒体约束,这是最明显的.REST接口意味着就像用户界面一样导航.REST接口返回资源的重新呈现.
REST接口应返回与用户界面显示方式无关的用户界面内容.
REST客户端< - > REST接口< - > BLL < - > DAL
在我看来,REST客户端有两种形式,非常薄的媒体类型渲染引擎(例如Web浏览器)或屏幕抓取器(蜘蛛,mashup).我松散地使用术语"屏幕刮板",因为如果您明智地选择媒体类型,那么客户端从您的用户界面内容中删除数据应该是微不足道的.
任何将业务逻辑层公开为REST接口的尝试通常都会产生一些影响.开发人员最终会询问如何在REST中进行事务处理.它们最终在客户端和BLL接口之间创建了大量的耦合,因为需要公开语义丰富的表示.他们忘记了所有关于超媒体约束的事情,因为大部分链接信息在业务逻辑层中不可用.他们开始抱怨HTTP和基于文本的内容类型的性能开销.
回答主要问题.不,不是真的.回答次要问题.以上都不是.
基于REST的体系结构不适合标准的3层模型.三层模型的简单视图如下所示:
表示层< - >业务逻辑层< - >数据层
考虑一下将表示层分成两部分,
渲染层< - >用户界面内容< - > BLL < - > DAL
如果您考虑常规Web应用程序,浏览器将获取HTML,CSS和Javascript内容,并在浏览器中以可视方式呈现它们.它是REST约束适用的用户界面内容层.如果您考虑超媒体约束,这是最明显的.REST接口意味着就像用户界面一样导航.REST接口返回资源的重新呈现.
REST接口应返回与用户界面显示方式无关的用户界面内容.
REST客户端< - > REST接口< - > BLL < - > DAL
在我看来,REST客户端有两种形式,非常薄的媒体类型渲染引擎(例如Web浏览器)或屏幕抓取器(蜘蛛,mashup).我松散地使用术语"屏幕刮板",因为如果您明智地选择媒体类型,那么客户端从您的用户界面内容中删除数据应该是微不足道的.
任何将业务逻辑层公开为REST接口的尝试通常都会产生一些影响.开发人员最终会询问如何在REST中进行事务处理.它们最终在客户端和BLL接口之间创建了大量的耦合,因为需要公开语义丰富的表示.他们忘记了所有关于超媒体约束的事情,因为大部分链接信息在业务逻辑层中不可用.他们开始抱怨HTTP和基于文本的内容类型的性能开销.
(1)避免让您的(非REST)Web服务业务逻辑层对数据访问层进行进一步(RESTful)HTTP请求.当然这样做比直接方法调用效率低.但更重要的是,它需要您将BLL Web服务和DAL Web服务部署到单独的Web服务器实例(或单独的集群)上.否则,您可能会遇到一个案例,其中所有 HTTP工作线程都忙于尝试提供BLL响应,并且每个线程都被阻塞等待无效的HTTP工作线程为DAL响应提供服务.这可能导致停顿(如果执行超时/重试处理)或彻底死锁(如果不这样做).
(2和3)如果您的Web服务客户端需要业务逻辑和数据访问,请将它们作为一组统一的服务提供.在内部,它们都依赖于相同的数据访问层方法调用:只是面向数据的Web服务实现只进行一次数据访问层调用,而面向业务逻辑的Web服务实现可以进行许多DAL调用.您确实希望在Web服务层下单独构建BLL和DAL层.
我喜欢将Web服务视为面向"用户"的表示层的一部分,而这些用户恰好是其他程序.