【问题标题】:API Design: Expose XML or Objects #2API 设计:公开 XML 或对象 #2
【发布时间】:2010-09-27 09:28:23
【问题描述】:

我最近问了这个问题:Expose XML or Objects - 感谢大家的回复。

澄清一点。

  • API 将始终被远程访问(即作为服务),最有可能通过 Web 服务或 WCF。

我同意理论上强类型 API 将对象公开为输入/输出是正确的方法。但是,我觉得公开 XML 仍有争议。在我看来,使用 XML 的原因是:

  1. 业务规则可由业务分析师在 Schematron 中编写。
  2. 接口是弱类型的,但只要调用它,就可以根据数据和业务规则验证数据。
  3. 服务的实现会更简单。无需创建领域对象模型。
  4. XML 架构已经定义(我们有一个架构数据字典)。
  5. 使用网络服务技术意味着基于 XML 的 API 不需要随着新汽车“类型”的添加而改变,例如

    void AddNewCar( string newCarXml )    
    string[] GetCars( /* some query conditions */ )
    

    如果我们使用基于对象的 API,那么添加新类型将需要一个新的查询方法来定义可以返回的可能派生类型(参见 extending web services)。像这样更新 Web 服务需要重新构建和重新部署此服务和所有现有客户端。

基于对象的 API 能给我们带来什么?一个强类型的声明式接口。它没有提供比 XML 更多的抽象(XML 本身就是一种抽象)。基于对象的 API 的成本是多少?它需要一整套需要业务规则和数据验证的域对象。

那么,我的问题是什么?给我一个不可战胜、无可争辩的理由,为什么我应该选择对象。

【问题讨论】:

    标签: c# web-services architecture n-tier-architecture


    【解决方案1】:

    如果您正在寻找支持 XML 的论据(不是我特别支持 XML)是:

    • 在涉及数据时,公开 XML 并提供 XSD 是不言自明的。您可以传递该表单中的所有数据,它是自我记录的,并且可以合理地简单地进行验证。

    • 我可以针对我的数据库或代码模型编写一堆安全代码,并且我可以以独立且安全的方式将数据发布给其他业务部门,需要最少的进一步文档或解释。

    • 它非常容易阅读,您通常可以像阅读文档或代码 cmets 一样轻松阅读它。

    然而,反对它的论点不断……说出最严重的违规者:

    • 过于冗长。
    • 巨大的网络开销。
    • 需要了解一项额外的技术,也许是不必要的 (?)。
    • 你做的事情越复杂,出错的机会就越大。

    【讨论】:

    • 谢谢。我正在寻找对象的论据。我需要对这个决定进行辩论,但目前可以看到双方,我无法坚决反对另一方。
    • 您的观点:过于冗长 - 同意。网络开销 - 我希望 WCF 堆栈会为我压缩调用(我需要对此进行调查)。额外的技术 - 也许。复杂性 - 我不确定 XML 是否比对象复杂。
    • @ng5000:更复杂的是对象已经存在,而 XML 不存在......(?)
    【解决方案2】:
    • 对象可以更好地执行(这里考虑二进制序列化)。
    • 对象可以有更强的简单类型验证。
    • 对象允许您将验证和业务规则置于更接近数据结构定义的位置。
    • 对象本质上允许您编写更简单的业务规则和验证,因为其中大部分都嵌入在对象定义本身中。
    • 对象也可以定义行为。
    • .Net 使通过序列化将对象转换为 Xml 并再次返回变得简单,从而为对象提供与 xml 相同的大部分好处。

    【讨论】:

      【解决方案3】:

      当您公开纯 XML 时,您的所有客户端都需要编写代码来生成和解析该 XML。在某些语言中很容易,在其他语言中是 PITA。

      但大多数语言都有 Web 服务 API,可以使用 wsdl/xsd 并在几秒钟内生成完整的客户端库。当然,他们必须编写一个映射实用程序来从他们的内部模型映射到您的模型以与您交互,但这是意料之中的。

      您的 Web 服务将在内部处理所有 ObjectXML 内容(对于客户端的视图),您无需担心 SOAP 和所有这些。您将定义您的界面:

      void addCar(Car newCar);
      Car getCar(String make, String model, String year);
      void removeCar(...);
      List<Car> getAllCars();
      

      这对您的客户来说很有意义。他们获取您的 wsdl 并使用 Java、C#、PHP、Python 等生成他们的客户端库。

      没有什么能阻止你添加:

      int addCarXML(String carXML);
      String getCarXML(int carID);
      

      但是为什么要添加两个级别的 webservice cruft - 首先是 wsdl,然后是 XML 模式的 xsds...

      【讨论】:

        【解决方案4】:

        强类型实际上任何类型都存在,唯一的原因是程序员不会犯任何愚蠢的错误(例如,将字符串传递给期望 int 的函数等)。最重要的是,这发生在编译时并且在运行时不花费任何成本,因此通过避免运行时检查(例如,正确的强制转换)和避免非托管代码在运行时的异常行为来生成高效的代码。

        就像你说的,Xml 可以用来定义一个替换对象模型,但是这个对象模型需要在运行时进行相同的检查,以在一定程度上保证可靠性。但这有一定的有限运行时开销。

        话虽如此,我想说的是,最终的选择是你的。您是否愿意放弃“刚性”对象模型所提供的安全性(有时是安心),或者您会更愿意使用更灵活但可以自己动手的对象模型? XML 需要更高的程序员纪律和警觉性(因此使用恕我直言是一件苦差事)。

        “基于对象”的 API 并不像您想象的那样死板,自动生成的 XML 模式可能无法完成您真正希望它们执行的操作。如果设计得当,基于对象的 API 可以像基于 XML 的 API 一样灵活。动态类型有时也有帮助。

        【讨论】:

          【解决方案5】:

          在网上查看有关 Contract-First Design 的文章,Spring 网站有一个很好的例子。我现在正在开发一个新的网站,并采取了从 XML Schema 开始并使用它来设计我的应用程序域模型的方法。 XML 非常适合在不同系统甚至应用程序层之间发送数据。它与编程语言无关,并且有许多工具可用于编辑、设计和实现基于 XML 的设计。

          它很冗长,但在事物的计划中,冗长是一个小烦恼。 它可以创建大文件,只需压缩它。 处理它的开销更大,但我们开发人员总是在用纯粹的性能来换取易用性、可维护性、可扩展性等。

          【讨论】:

            【解决方案6】:

            这是另一个随机的想法 - 两者都不使用;-p 我正在考虑其他交换格式。我最近在协议缓冲区方面做了很多工作——这提供了合同优先使用(通过“.proto”定义),但在设计时考虑到了安全的可扩展性——即你可以设计一些东西来传递意外数据而不会破坏或损失。不幸的是,主要的协议缓冲区规范实际上并不包括继承,但我的实现(protobuf-net)通过扩展来填充它。

            它是否足够成熟取决于场景 - 我只是认为它可能会引起人们的兴趣。顺便说一句,它(protobuf-net)还插入到 WCF 中,以方便预滚动的 RPC 堆栈;-p

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2022-12-05
              • 1970-01-01
              • 2010-09-07
              • 2011-12-14
              • 1970-01-01
              • 1970-01-01
              • 2010-10-22
              相关资源
              最近更新 更多