Versioning your API in .NET Core
Tags: rest, netcore, api, architecture
Published: 2021-07-08 12:37:33

Hi,

Sometimes we need to change the behavior or payload of our APIs. For these cases it is recommended to have a versioning API.

## Why do you need to versioning your API?

If your API is used by your websites, this is not a big problem because you can change these websites according the new requirements of our APIs.

On the other hand, if the API is consumed by mobile apps or third-party applications, its more complicated because you need release a new version of your apps and the users must install this new version in their mobile phones. So, in order to prevent errors and avoid breaking changes, it is important to have a versioning of your APIs.

## How do we add versions for my API?
In order to versioning your API in .NET Core, you need to do the following steps:

- In the API project, install the following nuget:
```powershell
Install-Package Microsoft.AspNetCore.Mvc.Versioning
```

- In the API project ConfigureServices()file method `startup.cs`, put the following code:

```csharp
 services.AddApiVersioning(x =>
            {
                x.DefaultApiVersion = new ApiVersion(1, 0);
                x.AssumeDefaultVersionWhenUnspecified = true;
                x.ReportApiVersions = true;
                x.ApiVersionReader = new HeaderApiVersionReader("x-api-version");
            });
```

Where:
&nbsp;&nbsp;`x.DefaultApiVersion` -> indicates the default version of the API.
&nbsp;&nbsp;`x.AssumeDefaultVersionWhenUnspecified`-> indicates if the default version of the API will be used if in the request header we don't indicate the version of the API.
&nbsp;&nbsp;`x.ReportApiVersions` -> indicates if we want to show in the response the available versions of the API.
&nbsp;&nbsp;`x.ApiVersionReader` -> indicates how we are going to send the API version in the request.

In our case, we will send the version of our API through the Header, in this way, we avoid that the applications that use the API do not have to modify their calls. In addition, we add more  security because we will send the version by header instead of querystring

## Adding versioning to your controllers

In order to add the versioning to your controllers, you only need to add the following decorator in your class `[ApiVersion("X.0")]`, where `X.0` will be the version number of your API for this class. In case your controller does not have this decorator, the API version for this class will be the default version (in our case "1.0").

**Controller without versioning**
```csharp
    [Route("api/[controller]")]
    [ApiController]
    public class DemoController : ControllerBase
    {
        [HttpGet]
        public IActionResult GetDemo()
        {
            return Content("Hola desde la versión por defecto");
        }
    }

```

**Controller with versioning**
```csharp
    [Route("api/[controller]")]
    [ApiController]
    [ApiVersion("2.0")]
    public class DemoController : ControllerBase
    {
        [HttpGet]
        public IActionResult GetDemo()
        {
            return Content("Hola desde la versión 2");
        }
    }
```

## Testing the versioning with Postman

#### Calling your API without API version in the Header

By default, the API will call the endpoint of the controller without specified version.

 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nu19i8q79fi02nw9hcvr.JPG)

#### Calling your API with API version = 1.0 in the Header

The API will call the endpoint of the controller without specified version again, because we set the default version of the API equals to 1.0

 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nu19i8q79fi02nw9hcvr.JPG)

#### Calling your API  with API version = 2.0 in the Header

In this case, the API will return a different response because it goes to the controller that has this version.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/crwvl3pwtea7x1j4rogw.JPG)

#### Calling your API with a version that doesn't exist

If the API is called with a version that does not exist, it will return "by default" a BadRequest (400) indicating that it does not support this version number

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/k507zlmpu23by21kyhds.JPG)

In addition, the API will inform you of the available versions that you can use, because we set the value of `ReportApiVersions = true` in the configuration.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/w4r1skptoms2g1zo8va1.JPG)

Finally, we already have our versioned api. You can find the github repository in this link:

https://github.com/jhonmarmolejo/NetCoreApiVersionDemo/tree/feature/ApiWithSwagger


See you next time!