Share types between API and client application

Asked

Viewed 144 times

7

I am developing a REST API using ASP.NET Webapi 2 and, as I come from the old SOAP standard, I’m used to type sharing between the API and the client. That is, when referencing my service in the client project, all types that are used in the API are created in the client project.

I’ve been thinking about how to do something similar, and I’ve been able to come up with three alternatives:

  1. Duplicate code between API and client
  2. Create a nuget package with the types (compiled or maybe the file itself .cs)
  3. Use anonymous types when making requests POST, PUT, etc. and use dynamic for requests of the type GET and the like

    GET:

    var clienteResponse = JsonConvert.DeserializeObject<dynamic>(response.Content);
    WriteLine(clienteResponse.Id);
    

    POST:

    var body = JsonConvert.SerializeObject(new
               {
                   Nome = "Jéferson",
                   Idade = 30                
               });
    
    req.AddParameter("application/json", body, ParameterType.RequestBody);
    var response = client.Execute(req);
    

Is this the best way to work? If so, is there any other way (or pattern) to share these types?

  • 1

    TL;DR: If the client platform is Strong typed, share the types. If not (web/javascript, for example) do not even care about it.

  • So I intend to have multiple client platforms. Most are applications winforms and some javascript. @lbotinelly

  • If winforms, and in the same language, a simple serializer/deserializer solves your problems, even if types are not strongly specified. The interface ApiController of Winapi 2, for example, maps properties of JSON objects to the properties of a new instance of the object.

  • Opinionated speaking, I would be in favor of using the types, and not necessarily using Nuget (I would make a Class Library for both). The dependency of a Nuget can be interesting if the serialization objects do not change much.

1 answer

5


There is no way to say what would be the "best way" to do this, it would give a huge margin for opinion, so I will try to express the pros and cons in each way.

Before looking at this you should see whether or not to share types between the server and the clients. There are some factors that can influence this decision, such as versioning, type errors (breaking the client like this), code duplication, possible errors in keeping the data between the client and the server, etc. These factors may influence whether or not you share data types.

If decided to share, you would have the two options you showed, duplicate the code or perform the versioning by dll’s/packages.

Duplicate Code

Pros:

  • Using this form you are ensuring that the typing will be the same between applications, thus causing no typing problems;

  • You will not have problems with serialization/decentralization because the types will be the same;

Cons:

  • Code duplication;
  • Possible type error that will cause application problems;
  • More work to keep codes up to date;

Nuget pack

You have the same structure as if you were going to duplicate the code, but you have the ease of versioning, thus making it less prone to errors, ensuring a "security" for communication between applications.

For example, if you have version 1.5.6 on the client and the server has 1.6 you may have some problems. With versioning you know what has changed and has caused problems, you know how to fix.

Now, if you don’t choose to share the types, you will have a different scenario.

Dynamic Types

Using this form you would not be sharing the types between the client and the server, that is, explicitly. A possible server modification would not "break" the client, and vice versa.

Pros:

  • Client model is less connected with the server, mirroring only the output, but not the types;
  • Server can be modified without risk to clients;
  • Allows improvements anywhere (client-server) without "breaking" the application.
  • Don’t worry about the guys;

Cons:

  • You do not have a contract between client and server;
  • It is not known when there is significant change that could cause problems;
  • Client and Server with different versions is more complex to find an error that could eventually happen;
  • Don’t worry about the guys;

Note that not to worry about the types is in pros on cons. The way you will handle the data will decide whether to be pro or against.

Completion

Using typesetting between systems will ensure a larger coupling, thus leaving more "security", if that is the word. However, you may have problems if you have a different type of application. Already without the set typing you will have "problems" of versioning and weak typing. There is no way to be sure that you will have these problems, but rather that there are possible problems that may appear in the course of the project.

There is no "better" way to do this. We don’t know about your project or how it would be applied in your application scenario.


There are some libraries that ~promise~ to accept the two types, the Expanding is one of them. At this link you have a tutorial if you want to check its functioning.

Note: Regardless of the options you are sharing the types, the difference is that one is explicit and the other is not.

References:

I have a certain weakness for using packages for greater control between systems. This way I will know exactly what has changed and where it has changed. If any problem happens, I will know where to fix it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.