本文介绍了我要一个Web API服务和客户端之间共享类型?什么其他选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在开发一个Web API RESTful服务来提供给我们的企业的所有应用程序访问常用数据。为了帮助我们还将发布封装所有HttpClient的细节,并提供了一​​个强类型的访问数据的客户端API。

We are developing a Web API RESTful service to provide access to common data to all the applications of our enterprise. To help we will also publish a Client API that encapsulate all the HttpClient details and provides a strongly-typed access to the data.

我们的目标是要从小做起,逐步增加新的功能,同时仍保持与客户端API(使用的相同主版本的客户端的兼容性)

Our goal is to start small and progressively add features, while still keeping backwards compatibility with already deployed versions of the client API (compatibility with the clients of the same Major version)

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

While talking about the design, our team just had a very long discussion about whether or not we should share types between the server and the client (for instance via versionned NuGet packages that both server and client would depend on), and ended up with pros and cons ... and we do not manage to decide one way or another.

赞成


  • 客户端模式和服务器模式始终是最新的

  • 没有串行化/反序列化的问题,因为同类型的序列化/反序列化

  • 没有重复

缺点


  • 需要找到一种方式来共享服务器和客户端之间的类型

  • 非语义的修改可以打破现有的客户端应用程序(改变一个类或者它的服务器型号命名空间的名称),即使对JSON序列化没有影响,所以应该没有影响

  • 没有意识到打破克林特风险

赞成


  • 客户端模式较少连接到服务器实现(只是一个服务器输出的JSON镜,但没有硬性同型的关系)

  • 服务器模式可以不破坏任何客户端的风险演变

  • 允许从服务器型号分别提高了客户端模型

  • 客户端模式是客户端软件包,没有共享包服务器和客户端之间维持一部分

缺点


  • 服务器code和客户端code之间的重复

  • 保持服务器端和客户端的结构同步容易出错的任务

有似乎是在我们的团队每个解决方案50/50 preference。

There seems to be a 50/50 preference for each solution in our team.

我个人有第二种选择一个preference,因为我相信剩下的就是所有关于脱钩,脱钩意味着客户端不应该关心如何在服务器端实现(其类型,或者它是否是一个。反正NET应用程序),但希望我们能摆脱可能出现重复,也许得益于code一代或类似的东西,但找不到任何关于这个问题的指导

I personally have a preference for the second option, because I believe RESt is all about decoupling, and decoupling means the client should not care about how the server side is implemented (which types, or whether it is a .NET app anyway) but wish we could get rid of the possible duplication, maybe thanks to code generation or something like that, but could not find any guidance on the subject

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

如果我们不同意他们的有没有方法来降低维护成本试图让客户端模式和服务器模式同步时

If we do not share them, are there ways to lower the maintenance costs when trying to keep client model and server model in sync ?

推荐答案

我认为,如果你不小心,第二个选项可能最终会被比第一少REST风格。 REST是少去耦,更多的是管理和重点客户端和服务器之间的耦合。

I would argue that if you are not careful, the second option could end up being less RESTful than the first. REST is less about de-coupling and more about managing and focusing the coupling between client and server.

在你知道客户机和服务器之间的耦合RESTful系统在于媒体类型定义和链接关系的定义。

In a restful system you know the coupling between client and server lies in the media type definitions and the link relation definitions.

在这两个选项中,你被有效地共享客户机和服务器之间的类型。在第一个选项这种共享是经由可管理作为一个的NuGet包和​​版本独立地客户机和服务器的一个具体实施明确的

In both options, you are effectively sharing types between the client and the server. In the first option this sharing is explicit via a concrete implementation that could be managed as a nuget package and versioned independently of client and server.

在第二个选项,你拥有共享类型的两种实现方法。不过,我猜你是不是在定义明确定义了这些类型的属性是媒体类型规划。因此,你有真理没有单一的来源,你什么都没有定义什么客户端和服务器之间的数据合同。你怎么知道你什么时候做出改变,这将打破客户端?至少在一个共享库就可以知道服务器现在使用的版本共享类型1.4.7和客户端使用1.3.9。您可以使用共享类型库语义版本,当你正在打破变化,这将迫使客户端更新就知道了。

In the second option you have two implementations of the shared types. However, I'm guessing you are not planning on defining a media type that explicitly defines what the properties of those types are. Therefore you have no single source of truth, you have nothing to define what the data contract between client and server is. How do you know when you are going to make a change that will break a client? At least with a shared library you can know that the server is now using version 1.4.7 of the shared types and the client is using 1.3.9. You can use semantic versioning on the shared type library to know when you are making a breaking change that will force the client to update.

通过第二个选项,你有一个客户端,并且将独立版本控制的secer,这将是更难跟踪是否有两个版本之间的重大更改。

With the second option, you have a client and a secer that will be independently versioned and it will be much harder to keep track of whether there are breaking changes between the two versions.

显式介质类型总是捕捉到合同和HTTP版本客户端和服务器之间的合同的最好方式。但是,如果你不想去那里,然后共享的NuGet库是最好的下一个步骤,因为要隔离是从客户端和服务器实现共享系统的一部分。这是REST的主要目标之一。你实际上共享该共享合同的实现库,这一事实不仅影响消费者住上不能占用图书馆其他平台。

Explict Media types are always the best way to capture the contracts and version the contracts between HTTP clients and servers. However, if you don't want to go there, then the shared nuget library is the best next step because you are isolating the part of the system that is shared from the client and server implementations. This is one of the key objectives of REST. The fact that you are actually sharing an implementation library of that shared contract only affects consumers live on other platforms that can't consume that library.

我在几年前创造了这个词 Web Pack中来形容这种想法使用一个共享的NuGet包包含共享耦合。我写了几篇文章和<一个href=\"http://www.biz$c$cr.com/using-nuget-to-give-web-api-that-add-service-reference-experience\">here关于这个问题的。

I coined the term Web Pack a few years ago to describe this idea of using a shared nuget package to contain the shared coupling. I wrote a few articles here and here on the subject.

这篇关于我要一个Web API服务和客户端之间共享类型?什么其他选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 06:58
查看更多