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.
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)
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.
Sharing types (shared assembly) between client and server
Pros
- Client model and Server model are always up to date
- no serializing/deserializing problems because same types are serialized/deserialized
- no duplication
Cons
- need to find a way to share the types between server and client
- non semantic modifications can break existing client applications (changing the name of a class or its namespace in the server model) even though it has no impact on the serialized json and should therefore have no impact
- risk of breaking the clint without realizing
Separate (but structurally equivalent) types for client and server
Pros
- client "model" is less coupled to the server implementation (just a mirror of the Json output by the server, but no hard "same type" relationship)
- server model can evolve without risk of breaking any client
- enable to enhance the client-side model independently from the server model
- the client model is part of the client package, no "shared package" to maintain between server and client
Cons
- duplication between server code and client code
- error-prone task of keeping server-side and client-side structure in sync
There seems to be a 50/50 preference for each solution in our team.
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
Are there other pros and cons to sharing types between client and server ?
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 ?