Seamless API Versioning with .NET FastEndpoints: A Simple Step-By-Step Guide

Handling Multiple versions of the same API gracefully is one of the common and yet difficult challenge in todays world of distributed application development. This post will help you through the process of implementing API versioning using a .NET application. We will be creating a FastEndpoints project, focusing on custom middleware and route management.

If you are new to FastEndPoints, Encourage you to go through this post : FastEndPoints Basics

Why API Versioning?

To ensure backward compatibility in a distributed application API-versioning plays a crucial role. It allows programmers to introduce new features, fix bugs, and make improvements without affecting existing clients. By managing different versions of API, you can offer a smooth transition for users while continuously evolving your service.

The Challenge with Duplicate Routes

Duplicate Routes is one common issue when implementing API-Versioning. This can occur when you try to manage multiple versions of the same API endpoint. FastEndpoints, a powerful library for building fast APIs in .NET, can help you manage this effectively.

Step-by-Step Solution: Versioning with FastEndpoints

Let's dive into a step-by-step guide on how to handle API versioning using FastEndpoints by creating version-specific routes and custom middleware.

 Step 1: Create a New .NET Web API Project

 First, create a new ASP.NET Core Web API project:

 dotnet new webapi -n VersionedApi

  cd VersionedApi

 Step 2: Install FastEndpoints

 Install the FastEndpoints package:

 dotnet add package FastEndpoints

 Step 3: Create Versioning Middleware

 The middleware will inspect the `API-Version` header and adjust the request path based on the version.

using Microsoft.AspNetCore.Http;

using System.Threading.Tasks;

public class VersioningMiddleware

{

    private readonly RequestDelegate _next;

 

    public VersioningMiddleware(RequestDelegate next)

    {

        _next = next;

    }

 

    public async Task InvokeAsync(HttpContext context)

    {

        var version = context.Request.Headers["API-Version"].ToString();

        if (string.IsNullOrEmpty(version))

        {

            context.Response.StatusCode = StatusCodes.Status400BadRequest;

            await context.Response.WriteAsync("API-Version header is required");

            return;

        }

 

        // Adjust the path based on the version header

        if (version == "1")

        {

            context.Request.Path = new PathString("/v1" + context.Request.Path);

        }

        else if (version == "2")

        {

            context.Request.Path = new PathString("/v2" + context.Request.Path);

        }

        else

        {

            context.Response.StatusCode = StatusCodes.Status400BadRequest;

            await context.Response.WriteAsync("Unsupported API version");

            return;

        }

 

        await _next(context);

    }

}

 

Step 4: Define Versioned Endpoints

 

Create separate endpoints for each version of your API.

 

  using FastEndpoints;

  using Microsoft.AspNetCore.Http;

  using System.Threading;

  using System.Threading.Tasks;

 

  public class ResourceV1Endpoint : EndpointWithoutRequest

  {

      public override void Configure()

      {

          Verbs(Http.GET);

          Routes("/v1/api/resource");

          AllowAnonymous();

      }

 

      public override async Task HandleAsync(CancellationToken ct)

      {

          await SendAsync(new { message = "This is version 1 of the resource" });

      }

  }

 

 

Version 2 Endpoint:

  using FastEndpoints;

  using Microsoft.AspNetCore.Http;

  using System.Threading;

  using System.Threading.Tasks;

 

  public class ResourceV2Endpoint : EndpointWithoutRequest

  {

      public override void Configure()

      {

          Verbs(Http.GET);

          Routes("/v2/api/resource");

          AllowAnonymous();

      }

 

      public override async Task HandleAsync(CancellationToken ct)

      {

          await SendAsync(new { message = "This is version 2 of the resource" });

      }

  }

 

 

 Step 5: Configure Middleware in `Program.cs`

 

Add the versioning middleware and configure FastEndpoints in your `Program.cs`.

 

using FastEndpoints;

using Microsoft.AspNetCore.Builder;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Hosting;

 

var builder = WebApplication.CreateBuilder(args);

 

builder.Services.AddFastEndpoints();

 

var app = builder.Build();

 

app.UseMiddleware<VersioningMiddleware>();

 

app.UseRouting();

app.UseEndpoints(endpoints =>

{

    endpoints.MapFastEndpoints();

});

 

app.Run(); 

Running and Testing Your API

 

After setting up your project, run the application:

 

bash

dotnet run

 

You can test the application using `curl` or Postman by setting the `API-Version` header:

 

- Version 1 Request:

 

  curl -H "API-Version: 1" http://localhost:5000/api/resource

 

 

- Version 2 Request:

 

  curl -H "API-Version: 2" http://localhost:5000/api/resource


- Postman

Postman Web Request for FastEndPoints
FastEndPoints Request via Postman


 

Check out the YouTube video : 



Conclusion

Having a custom middleware by leveraging FastEndPoints, you will be able to effectively manage the API-Versioning in your application. This approach ensures there are no route conflicts and provides a clear separation of different API versions. Maintaining a scalable and robust API has never been easier with FastEndpoints.

 

 

Comments

Popular posts from this blog

Creating RESTful Minimal WebAPI in .Net 6 in an Easy Manner! | FastEndpoints

Mastering Concurrency with Latches and Barriers in C++20: A Practical Guide for Students

Graph Visualization using MSAGL with Examples