1

I have multiple REST-ful APIs that I'm using as my "back-end". I also have multiple web apps (.NET MVC). These web apps make calls to the APIs for data. So, an object being returned by an API will be the same as the object being expected on the web app side (serialized from JSON of course).

For example, if my web app makes a call to an API for a Customer object, that same object will be used across both the API and web app projects.

So, the question is, how do you manage this scenario (create NuGet packages for shared objects/interfaces, duplicate code, etc.)?

4 Answers 4

2

It is just a DTO with the same properties. I would strongly suggest just copy it between the server and the client.

See also this StackOverflow answer that has the same conclusion

The reason is, in reality, once you have a wire format it is very difficult to change once the system is in production. Unless you deploy server and client at the same time which will include increased risk and downtime. That means normally we cannot just rename fields. A rename will include adding a new field - then at a later release delete the unused field. With this in mind, we see that we gain nothing from sharing the DTO in a NuGet or shared assembly.

4
  • Thanks for the response. This is the way I was leaning also. I don't like the duplicate code, but it's propably the way to go. Adding a package for each API's DTOs and Interfaces seems like it would add more complexity to deployments than it would be worth. Apr 17, 2019 at 23:01
  • Couldn't you use this same approach (open for extension, closed for modification) with a shared DTO nuget package and get the best of both worlds?
    – Joe Eng
    Mar 21, 2020 at 19:25
  • I found the answers in this post provided pretty good reasons not to share DTO libraries: softwareengineering.stackexchange.com/questions/366235/…
    – Joe Eng
    Mar 21, 2020 at 19:34
  • @lioneltwain: The duplicate code becomes a non-issue when you have the BE build generate the FE dtos for you. We usually work in projects where both the DTOs and the repositories (FE, TypeScript) are generated for us, so you don't need to write it yourself. It's all very boilerplate logic that can be derived from the api controllers themselves.
    – Flater
    Sep 20, 2020 at 23:19
3

Most commonly you would need an assembly that defines the DTO objects that is shared between the front end and the back end. That doesn't necessarily have to be a NuGet package. It can simply be another project in the same solution that your other projects reference directly.

3
  • Each API and Web App is in its own solution. That's why I was considering NuGet packages. But that seems like overkill as you would need a NuGet per API. Apr 16, 2019 at 17:55
  • If you have your own NuGet repository (like Sonatype Nexus, or Microsoft Team Foundation Server) then it's perfectly fine to have a NuGet package. It's not worth it necessarily to share that code with the whole world. Apr 16, 2019 at 20:23
  • Sorry, I would be using an internal NuGet repository for packages. I should have specified. Apr 16, 2019 at 20:45
3

Do all of the projects that will use your models reside in the same solution?

If so, then don't use NuGet. You can- but keep in mind that the Visual Studio debugger won't respect breakpoints in blocks of code that are referenced as packages.

If not, then definitely use a NuGet package to share your models. Doing so can save you a lot of heartache when you need to update your models.

Deploying your models in NuGet packages will allow you to use different versions of your models across different projects, thus you won't need to update every single project when you make a change to those models.

This is how I do this stuff:

  • Save your models into .NET Standard libraries (unless you have a specific reason not to)
  • If you want to share the models with a project in a different solution, then deploy the .NET Standard libraries as NuGet packages (and install those packages in your other solution's projects)
  • If you only need to share the models with projects in the same solution, then just add a (project) reference to the models library

If I ever need to debug the models project from one of my APIs that uses the models NuGet package, then I'll just swap the package reference for a project reference. You have to ensure that the local models project is in the same state as the referenced package before you begin debugging- but it doesn't take much time to do (if you're using Git or some other source control).

I hope this helps someone! BTW, this type of distribution works well for other types of projects as well- not just models!

4
  • It's worth noting that JetBrains' Rider can automatically decompile and step into code in NuGet packages. You can do it with ReSharper too in Visual Studio but I don't think it's automatic. That said, most devs I have known and worked with use VS. I'd say 99%.
    – jspinella
    Dec 21, 2020 at 15:12
  • @jspinella thank you for tipping me off about that capability! I've been using ReSharper for a long time and never knew it provided that as a feature... For anyone else interested, I used the following, but I also checked the "Microsoft Symbol Servers" and "NuGet.org Symbol Server" as it seemed like this would be a requirement: jetbrains.com/help/resharper/Debugging_Without_Source_Code.html Dec 23, 2020 at 8:04
  • ... I also checked the "Microsoft Symbol Servers" and "NuGet.org Symbol Server" (Options|Debugging|Symbols|Symbol File (.pdb) locations) as it seemed like this would be a requirement. Finally, I made sure that "Load all modules, unless excluded" was selected (in that same options window). It didn't work without that. I'm not sure how much of this is ReSharper and how much is Visual Studio. Maybe someone without ReSharper could give this a shot and see if they can manage to hit a breakpoint? Dec 23, 2020 at 8:08
  • I haven't used ReSharper in some time and when I did use it I did not use the dotPeek integration to step into NuGet packages. Theoretically any third-party NuGet package your app uses, the debug symbols can be downloaded from the NuGet.org Symbol Server. I'm not sure how common it is for devs of packages to bother uploading symbol packages alongside their library's NuGet package. If everyone did that, it seems like dotPeek VS integration would be obsolete as we wouldn't need to decompile to get the .pdb files. It's probably a nice feature for large companies with a lot of internal NuGet pkgs.
    – jspinella
    Dec 25, 2020 at 17:57
0

I like the Nuget approach best, and more so in conjunction with CQS (A web api only exposing a ExecuteQuery and ExecuteCommmand and than a shared contracts library with all the command / queries)

But you can also use Swashbuckle (Swagger).

Install-Package Swashbuckle.AspNetCore

And add

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});

More info https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-2.2&tabs=visual-studio

You can now generate a swagger client for example with NSwag (Covered in above article).

Again, this is just posted as an alternative, personally I like the shared library approach better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.