我应该在Web API服务和它的客户端之间共享类型吗?还有什么其他选择?

tsi*_*lar 44 .net asp.net-web-api dotnet-httpclient

我们正在开发Web API RESTful服务,以便为我们企业的所有应用程序提供对公共数据的访问.为了帮助我们,我们还将发布一个客户端API,它封装了所有HttpClient详细信息,并提供了对数据的强类型访问.

我们的目标是开始小规模并逐步添加功能,同时仍然保持与已部署版本的客户端API的向后兼容性(与相同主要版本的客户端兼容)

在谈到设计,我们的团队刚刚约了很长的讨论,我们是否应该共享的服务器和客户端之间的类型(通过versionned的NuGet包实例服务器和客户端将取决于),并结束了与利弊和缺点......我们无法决定这种或那种方式.

在客户端和服务器之间共享类型(共享程序集)

优点

  • 客户端模型和服务器模型始终是最新的
  • 没有序列化/反序列化问题,因为相同类型被序列化/反序列化
  • 没有重复

缺点

  • 需要找到一种方法来共享服务器和客户端之间的类型
  • 非语义修改可以破坏现有的客户端应用程序(在服务器模型中更改类的名称或其名称空间),即使它对序列化的json没有影响,因此应该没有影响
  • 没有意识到打破克林的风险

客户端和服务器的单独(但结构上等效)类型

优点

  • 客户端"模型"较少耦合到服务器实现(只是服务器的Json输出的镜像,但没有硬"相同类型"关系)
  • 服务器模型可以发展而没有破坏任何客户端的风险
  • 能够独立于服务器模型增强客户端模型
  • 客户端模型是客户端软件包的一部分,在服务器和客户端之间没有"共享软件包"

缺点

  • 服务器代码和客户端代码之间的重复
  • 保持服务器端和客户端结构同步的容易出错的任务

我们团队的每个解决方案似乎都有50/50的偏好.

我个人有第二种选择的偏好,因为我相信其余的都是关于去耦和去耦意味着客户端不应该在乎如何在服务器端实现(其类型,或者它是否是一个.NET应用程序反正),但希望我们可以摆脱可能的重复,也许可以归功于代码生成或类似的东西,但无法找到关于这个主题的任何指导

在客户端和服务器之间共享类型还有其他优缺点吗?

如果我们不共享它们,是否有办法在尝试保持客户端模型和服务器模型同步降低维护成本

Dar*_*ler 22

我认为,如果你不小心,第二个选项最终可能比第一个选项更少RESTful.REST不是关于解耦,而是关于管理和聚焦客户端和服务器之间的耦合.

在一个安静的系统中,您知道客户端和服务器之间的耦合在于媒体类型定义和链接关系定义.

在这两个选项中,您实际上是在客户端和服务器之间共享类型.在第一个选项中,此共享通过具体实现显式化,该实现可以作为nuget包进行管理,并且独立于客户端和服务器进行版本控制.

在第二个选项中,您有两个共享类型的实现.但是,我猜你没有计划定义一个明确定义这些类型属性的媒体类型.因此,您没有单一的事实来源,您无需定义客户端和服务器之间的数据协定.你怎么知道什么时候你会做出一个会破坏客户的改变?至少使用共享库,您可以知道服务器现在使用的是1.4.7版的共享类型,而客户端正在使用1.3.9.您可以在共享类型库上使用语义版本控制来了解何时进行重大更改以强制客户端更新.

使用第二个选项,您有一个客户端和一个将独立版本化的secer,并且很难跟踪这两个版本之间是否存在重大变化.

Explict媒体类型始终是捕获合同并在HTTP客户端和服务器之间对合同进行版本化的最佳方式.但是,如果您不想去那里,那么共享nuget库是最好的下一步,因为您正在隔离从客户端和服务器实现共享的系统部分.这是REST的主要目标之一.您实际上共享该共享协定的实现库这一事实仅影响在不能使用该库的其他平台上的消费者.

Web Pack几年前我创造了这个术语来描述使用共享nuget包来包含共享耦合的想法.我在这里这里写了几篇关于这个主题的文章.

  • 鉴于您是Microsoft的人,我看到您提倡在客户端和服务器中共享的强类型定义.这遵循微软的历史方法,可追溯到分布式COM,以及WCF(SOAP).非常喜欢RPC.WebApi利用默认模型绑定器支持这种意识形态.我已经与非以微软为中心的开发人员进行了讨论,并发现有时会推动另一种方式 - 减少共享,减少类似RPC,服务从有效负载中获取尽可能多的东西 - 减少并发症和框架.这似乎已成为一个宗教辩论主题.不确定我的立场...... (2认同)

小智 13

我们进行了类似的讨论 - 具有类似的优点和缺点 - 我们采取了混合方法.我们在客户端和服务器之间共享一个程序集,但只共享接口.然后我们基于客户端的接口创建了类.优点是客户端和服务器上的实际对象可以独立更改.