Skip to main content

Command Palette

Search for a command to run...

Designing REST APIs in .NET 5

Learn best practice such as Configuring Swagger, API Versioning, use of DTOs, and Repository Pattern.

Updated
11 min read
Designing REST APIs in .NET 5
G

I am Gabriel, a software developer from Uyo, Nigeria. I'm a graduate of Chemical Engineering but my passion for tech led me into a career in software development.

REST stands for Representational State Transfer and it is a specification for building APIs. This standard is language agnostic which means it applies to building APIs in any language of choice. This article does not go in depth in explaining the concept of REST but shows you how to fully design APIs with best practices adhered to.

.NET 5 is the new .NET framework which unifies the existing .NET Core and .NET Framework and with it, you can build desktop, mobile, web, IoT, cloud and machine learning applications.

To build an API in .NET is really easy, with the help of Visual Studio, you can get started almost immediately.

Firstly, you open Visual Studio from your local machine and click Create new project then you go ahead to select the ASP.NET Core Web Application which gives you a prompt to choose a template, you select the API template and choose the version as ASP.NET Core 5.0.

API 1.PNG

We would call our Web API, MovieApp.API. After the project has been created, we can now design our API. Create a folder called Models and add a class item, GenreModel.cs. Inside the class we would have 3 (three) properties namely, Id (Guid), Name (string), and DateCreated (DateTime).

API 2.PNG

Go ahead to create a Data folder and add a class, ApplicationDbContext.cs. Inside the class you would register the internal data access layer (Model). But for this to be successful you would have to add the following nuget packages via the Package Manager Solution:

  • Microsoft.EntityFrameworkCore

API 3.PNG

For the GenreModel.cs to be registered as a table on the database, you would have to connect the application to the database using a connection string saved in the appsettings.json file.

API 4.PNG

For the application to access the table in the database, it has to be configured as a service in the DI (Dependency Injection) Container located in the Startup.cs file. The following nuget package should be added:

  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.SqlServer

API 5.PNG

After the above configuration has been done, you can now add migrations to the database using the package manager console, if the migration was successfully created, you can then go ahead to update the database to see the changes on the migration in the database.

API 6.PNG

API 7.PNG

Since we are sticking to best practice we would be employing the use of the repository pattern, this helps in the separation of concerns. Go ahead to create a folder called Repository and a sub folder called IRepository. Inside the IRepository folder, add an interface, IGenreRepository this would hold the contract for the CRUD (Create, Read, Update and Delete) operation we intend to implement.

API 8.PNG

Add a class to the Repository folder called GenreRepository, this class would inherit from the interface and would implement the interface contract initialized above.

API 9.PNG

API 10.PNG

After implementing the interface, you would have to inject the Repository as a service into the DI Container to be able to access them across the application.

API 11.PNG

You can then go ahead to create a Controllers folder and add a new Controller Item called, GenresController. Inside the Controller we would create actions for Create, Read, Update, and Delete. This implies the controller actions would be making HTTP calls such as the GET, POST, PUT, PATCH and DELETE request to the server and these returns with a response. A GET request returns a 200 OK response, a POST request returns a 201 CreatedAtRoute response, a PUT request returns a 204 NoContent response, a PATCH request returns a 204 NoContent response, and a DELETE request returns a 204 NoContent response.

Create a DTO folder inside the Models folder and add a GenreDTO.cs class. Inside the DTO folder create another folder called, MovieAppMapper, inside the folder add a class MovieMapper.cs. Inject the mapping profile into the MovieMapper constructor. You would have to add the following nuget packages to complete this action:

  • AutoMapper
  • AutoMapper.Extensions.Microsoft.DependencyInjection

API 12.PNG

API 13.PNG

Go to the Startup.cs class and inject the AutoMapper into the DI Container

API 26.PNG

Before you can use the Repository, you injected into the service container, you would have to inject it into the constructor of the Controller. We would also be using DTOs properly known as Data Transfer Objects. This helps in automatically mapping the properties to the model and for displaying just the data you intend the client to see.

API 14.PNG

For making a GET request to the server to retrieve all the resources in the database, we create a GetAllGenre action. In this action, a request is made to the datacontext which then retrieves all the resources, the resource is then mapped into the DTO.

API 15.PNG

For making a GET request to the server to retrieve a specific resource in the database, we create a GetGenreById action which collects a Guid parameter. In this action, a request is made to the datacontext based on the guid parameter passed, if this is available, it returns the specific resource and maps it to the DTO.

API 16.PNG

A Create Http action to the server makes a POST request to create a new resource in the database based on the content of the DTO passed. This performs checks such as whether Genre name exist and ModelState is valid, if this is validated it then maps the DTO into the model before creating the new resource.

API 17.PNG

API 18.PNG

An Update Http action to the server makes a PUT request to update parts or all of the resource in the database based on the genreId and the content of the GenreDto passed. This checks if the resource is available then maps it into the model before updating the resource in the database.

API 19.PNG

There is also another Update Http action but this updates only one part of the resource in the database based on the id and JsonPatchDocument passed into the PartialUpdateGenre action. Its is called a PATCH request. Before you can successfully carry out the PATCH request you would have to install the following nuget package:

  • Microsoft.AspNetCore.JsonPatch
  • Microsoft.AspNetCore.Mvc.NewtonsoftJson

API 20.PNG

Go to the startup.cs file and configure Newtonsoft.json into the DI Container in the ConfigureServices method. Do well to add the appropriate namespaces.

API 28.PNG

Finally, the Delete Http action makes a DELETE request to the server to delete a particular resource from the database based on the id passed in.

API 21.PNG

We are almost set, what remains is to configure swagger and API versioning into the application.

Swagger is an interface description language for describing RESTful APIs expressed in Json. Before configuring Swagger and API versioning in the application, we would have to install the nuget packages:

  • Swashbuckle.AspNetCore
  • Microsoft.AspNetCore.Mvc.Versioning
  • Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer

Create a class on the root of the directory, called ConfigureSwaggerOptions, inside the class, you would configure the Swagger and API versioning.

API 22.PNG

Go the Startup.cs class and inject the Swagger and API versioning services in the ConfigureServices DI Container.

API 23.PNG

On the Configure method still inside the Startup.cs class you would configure Swagger into the middleware.

API 24.PNG

You can now add the routing and versioning on the controller.

API 27.PNG

Finally delete the following options in the launchSettings.json file for the IISExpress and run the project and test the application on the Swagger Client.

API 25.PNG

Below is how the Swagger Client / Doc looks like. You can now go ahead to test all the API endpoints we've built and see if they work.

API 29.PNG

Designing a RESTful API in .NET is somewhat simple if you followed all the following steps. You can add functionalities such as Securing the API with JWT (Json Web Tokens), adding XML Comments for documentation on Swagger. In the next tutorial we would be looking at Unit testing the API controller.

D

My leader sir, I am here again ooooo.

Apparently, I have concluded the code along of the above project, like I noted in my last question when I scaffold a new project template, it already came with a Swagger template already registered in the Startup class. However, I commented out the default swagger registration in the startup class so I could follow yours as described above but when I run the project it throws an error. When I launch the project it goes to this path https://localhost:44366/swagger/index.html and I see a default swagger UI similar to yours. But when I navigate to /genre it throws an error "This localhost page can’t be found No webpage was found for the web address: https://localhost:44366/genre HTTP ERROR 404"

Here is a link to my github repo of my codes https://github.com/dyagzy/.Net5RestApi

I will appreciate if you can help debug this... now I will move on to code up the Unit test project while I wait for you...

Thank you in advance chief.

1
G
Gabriel5y ago

Okay. Do you know how to use Swagger? When using Swagger you don't have to change the URL or navigate to any of the actions. The documentation provides ways on how to go about it. You simply just have to click on the endpoint you want to test and follow the instructions and it calls the data you need.

I

Thank you for taking the time to elaborate on the above subject. I am still kind of new to the tech so permit me to ask the following naive questions.

  1. Why did you have to configure swagger again when by default swagger is already configured to the start up class of the. Net5.0 project template?

  2. How did you come about all the data annotations and why did you have to use them on all those controller action methods?

  3. I didn't really get the difference between the Update Patch method and why you have to use a JsonPatchDoc and all that.

  1. You didn't specify the version number for each of the various nuggets packages you installed am asking because I still get confused on how to know which package number to install on a particular project especially when such a package has different variations of it's packages.

  2. For the application to access the table in the database, it has to be configured as a service in the DI (Dependency Injection) Container located in the Startup.cs file. You didn't show the code section for this, I think it was an omission.

  3. I am new to everything you had described above so I would like to code along then revert back to you if I have a bug or if I have more questions. Once again I am very grateful for the opportunity to learn from you via this article.

1
G
Gabriel5y ago
  1. I added some custom configuration to add API Versioning into the Swagger Doc in the ConfigureSwaggerOptions class so this demands that I reconfigure the existing configuration model.

  2. The data annotations I used are built into the ASP.NET Core runtime. I added them as part of the documentatng status code into Swagger Documentation which is available when you run the application.

  3. Using JsonPatchDoc is .NET best practice for PATCH REQUEST. It is different from PUT. PATCH request updates only one part of the resource while with PUT you can update one or more part of the resource.

Check https://docs.microsoft.com/en-us/aspnet/core/web-api/jsonpatch?view=aspnetcore-5.0 for more on configuring and using PATCH request.

  1. If you're using .NET 5 to follow along you can install the latest version of the nuget package.

  2. It's was not omitted. Might be a network challenge from your end.

  3. Thanks for your comprehensive feedback. I'm always available if you have more questions.

I

Thanks for sharing

1