OpenAPI defines a way for web services to clearly define their API for automatic and correct client library generation, and with NSwag, clients for these APIs can be automatically generated for C#. What’s more, rather than generating the source code for these clients manually, a service reference can be added to your .csproj file to generate these clients transparently and automatically at development-time and build-time, —essentially It Just Works! This is truly an amazing (although not specifically unique,) benefit of the .NET tooling ecosystem; any IDE which plugs into the common .NET C# language backend (VS, Code, Rider, you name it) will immediately see and present the generated API client classes and their methods in type suggestions, without anything files having to be compiled or included manually by the developer.
Today I’ll write on how to go about this via a dotnet command-line tool; applicable regardless of the IDE or development platform you use. Whilst Visual Studio users get a simple (and obvious) wizard for adding these API service references, the information regarding the platform-agnostic command-line version seems to be scattered across the ASP.NET Core docs, and personally I felt it was quite obscure and challenging to find. Hopefully this blog post speeds up this process for any other developers going through these same steps for the first time.
A recent uni assignment has required me to implement an ASP.NET Core REST API using EntityFrameworkCore on a pre-existing database. Whilst EF Core tends to generate controllers for models with single primary keys just fine, I’ve found that it has no support for composite primary keys. This requires you to alter your controller classes to add the support manually, which in my case involved the following;
- Alter the paths of the individual Get, Put, and Delete endpoints to contain two (or more, depending on how many keys are in your composite) parameters, and then alter the method parameters to match. This requires careful consideration as there are many different ways you can structure the parameters in your route.
- Alter every usage of _context.nameOfModelHere.FindAsync to contain all components of your primary key. Look at the model’s Entity definition in your database context class, specifically the usage of entity.HasKey, to determine the order in which to list the components in your key to FindAsync.
- Alter the nameOfModelHereExists method to take the correct amount of parameters for your key. Adjust the body of the method accordingly to check all parts of the key; I just added && at the end of the existing equality expression, and added more equality expressions.
- Alter all usages of nameOfModelHereExists appropriately.
- In the Put method, alter the second if statement to check all the components of your primary key, rather than just id.
- In the Post method, adjust the CreatedAtAction call in the return statement to contain all the components of your primary key.
- I would also recommend updating all the auto-generated comments that EntityFramework put in to keep things consistent.