企业服务总线(ESB)是企业应用集成的中心枢纽,它允许不同系统之间通过消息传递进行通信。在本文中,将探讨ESB中消息的格式和转换问题,以及在实现或重构ESB时需要考虑的因素。
在ESB的上下文中,消息通常是指从一个系统流向另一个系统的数据。更具体地说,这些消息是由一个系统发布,然后被转换以供一个或多个其他系统消费。因此,描述同一个“事务”可能涉及多个消息,而设计这些消息时应考虑多种因素。
消息可以采用各种格式。然而,通常情况下,源系统的应用程序设计者会选择遵循某些标准,以便于创建消息,同时也便于消费者理解,因为消费者可能了解格式规范,从而知道可以期待什么。
在大多数情况下,系统能够生成JSON或XML格式的消息。在出现更好的替代方案之前,强烈建议使用这两种格式之一进行事务性消息的传输,并尽可能避免使用自定义格式。JSON和XML都具有自解释和明确的优势,因为它们是可读的,并且容易理解,无论是数据内容(如果值被赋予了有意义的名称)还是数据类型。
JSON和XML在许多方面都不相同,尽管关于它们之间的选择常常带有宗教色彩的讨论,但它们之间确实存在一些值得考虑的差异。
首先,XML可以通过XSD定义特定消息类型的描述,即定义消息应遵循的定义、消息结构、可能存在或必须存在的字段、它们的基数和数据类型以及任何附加属性。这是数据生产者创建的定义,可以说是对交付内容的描述。基于此,可以对消息进行非常严格的验证。对于一些应用程序来说,如果没有至少伴随一个命名空间,XML就无效——一个XML文档/消息类型是由其命名空间和根元素名称唯一定义的。然而,XML也可以以更宽松、无命名空间的方式使用。
JSON没有这些。它更精简——这可能是其受欢迎的原因之一——并且它非常容易阅读。然而,仍然可以创建一个模式来描述JSON应该是什么样子。这种合同可能在RAML文件中描述,但与XML不同,这通常是由消息的接收者设置的,以确保对接收的消息有规则,并提供一种拒绝不符合格式的消息的手段。
并不是XML的倡导者。发现JSON非常灵活——它与Java对象的紧密相似性以及轻松转换为Java和JavaScript对象的能力,使得JSON在许多情况下都非常有吸引力。在之前的文章中,已经展示了如何在一个精简的ESB实现中在所有点上使用JSON,以及如何使用基于模板的转换工具进行转换。这种实现只是基础性的,主要是为了启发,但它确实概述了一个原则,并且使用模板工具可能会成熟到企业级。
但是,认为值得考虑这些格式的优点以及它们与ESB的关系:JSON简单且广泛支持(很难找到一个不实现某种JSON支持的编程语言),它不一定与格式规范绑定,但在接收端可以进行验证——简而言之,它非常适合ESB的API/前端。
另一方面,XML在转换上下文中非常强大。有一个标准化的语言来识别和查找元素(XPath)和转换整个文档(XSLT)。
在ESB环境中,XSLT转换工具当然特别有趣。认为,为接收JSON并将其转换为XML的API提供服务是一个有趣的案例。然后,从那里,消费者可以使用XSLT提取/转换为相关文档,如果需要,这个文档可能在交付之前被转换回JSON。
(请注意,在将XML转换为JSON的结构性挑战之一——标签属性——在描述的方案中可能完全避免)。
这只是一个思想实验,但认为它提供了很多。它还暗示开发人员需要熟练处理JSON和XML。然而,这个提议也触及了另一个常见要求:需要在处理单个消息时有更多的步骤。在描述的方案中,所有传入的消息都将被转换为XML,然后发布到路由机制,即发布到Rabbit MQ的一个或多个交换。然后每个消费者将通过XSLT转换相关(订阅的)消息。最后,XML文档可能被转换为JSON以交付到目标系统。
创建这些步骤的简单方法是在每个步骤之间将消息发布到路由机制。这会带来队列或通道等的开销,但它也提供了一个很好的洞察,了解可能在哪里失败,并提供了出色的调试机会。
整个设计的美妙之处在于所有组件都可以是完全通用的:接收JSON消息并将其转换为XML的Web服务。转换都是相同的,只是消息和XSLT不同,所以这应该在消费者实例化时是可配置的。最后,从XML到JSON的转换可以再次是通用的。