Управление версиями REST API — критически важный аспект поддержания успешного и хорошо разработанного API. Включая номер версии в URL-адрес или заголовки HTTP-запроса, разработчики могут гарантировать, что клиенты API используют правильную версию и могут вносить изменения в API, не нарушая работу существующих клиентов. Существует несколько различных подходов к управлению версиями REST API, включая использование номера версии в URL-адресе, использование заголовка Accept и использование настраиваемых заголовков. В этой статье мы рассмотрим различные подходы к управлению версиями REST API и обсудим плюсы и минусы каждого подхода. Мы также рассмотрим некоторые рекомендации по реализации версий REST API в ваших собственных проектах.

Когда дело доходит до создания REST API в .NET, важно учитывать управление версиями. Включая номер версии в URL-адрес или заголовки HTTP-запроса, разработчики могут гарантировать, что клиенты API используют правильную версию и могут вносить изменения в API, не нарушая работу существующих клиентов. Существует несколько различных подходов к управлению версиями REST API в .NET, включая использование номера версии в URL-адресе, использование заголовка Accept и использование настраиваемых заголовков. В этой статье мы рассмотрим различные подходы к управлению версиями REST API в .NET и обсудим плюсы и минусы каждого подхода. Мы также рассмотрим некоторые рекомендации по реализации версий REST API в ваших проектах .NET.

Одним из распространенных подходов к управлению версиями REST API в .NET является использование номера версии в URL-адресе. Например, URL-адрес API версии 1 может выглядеть так:

https://www.example.com/api/v1/

Преимущество использования номера версии в URL состоит в том, что его легко понять и реализовать. Это также дает понять клиентам API, какую версию они используют. Однако использование номера версии в URL-адресе может затруднить одновременную поддержку нескольких версий API. Это также может затруднить внесение изменений в API, поскольку любые изменения, нарушающие работу существующих клиентов, потребуют изменения URL-адреса API.

Другой подход к управлению версиями REST API в .NET — использование заголовка Accept. Это позволяет клиенту API указать версию API, которую он хочет использовать. Например, клиент может отправить такой запрос:

GET /api/products HTTP/1.1
Host: www.example.com
Accept: application/vnd.example-v1+json
ample-v1+json

Преимущество использования заголовка Accept заключается в упрощении одновременной поддержки нескольких версий API. Это также позволяет поставщику API вносить изменения в API без изменения URL-адреса. Однако использование заголовка Accept может быть более сложным в реализации и может быть не таким интуитивно понятным для клиентов API.

Третий подход к управлению версиями REST API в .NET — это настраиваемые заголовки. Это позволяет поставщику API указывать версию API в пользовательском заголовке HTTP, а не в URL-адресе или заголовке Accept. Например, поставщик API может указать версию API следующим образом:

GET /api/products HTTP/1.1
Host: www.example.com
X-API-Version: 1
HTTP/1.1 Host: www.example.com X-API-Version: 1

Преимущество использования настраиваемых заголовков заключается в гибкости и возможности поставщику API выбирать наилучшую схему управления версиями для своего API. Однако его также может быть сложнее реализовать, и он может быть не таким интуитивно понятным для клиентов API.

Настройка версий API в .Net 6

Чтобы настроить управление версиями API в .NET, необходимо установить два пакета NuGet:

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

Эти пакеты обеспечивают поддержку реализации версий API и создания метаданных об API соответственно. Вы можете установить оба пакета с помощью следующей команды:

dotnet add package Microsoft.AspNetCore.Mvc.Versioning
dotnet add Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer

После установки пакетов вы можете использовать их для добавления информации о версии в конечную точку URL вашего API или в заголовки запросов. Это может помочь вам поддерживать обратную совместимость и управлять несколькими версиями вашего API. Метаданные, сгенерированные пакетом ApiExplorer, могут быть полезны для создания интерактивной документации или для тестирования конечных точек API.

вам нужно добавить следующий код в Program.cs после установки пакетов.

builder.Services.AddApiVersioning(opt =>
{
    opt.DefaultApiVersion = new ApiVersion(1, 0);
    opt.AssumeDefaultVersionWhenUnspecified = true;
    opt.ReportApiVersions = true;
    opt.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
                                                    new HeaderApiVersionReader("x-api-version"),
                                                    new MediaTypeApiVersionReader("x-api-version"));
});

builder.Services.AddVersionedApiExplorer(setup =>
{
    setup.GroupNameFormat = "'v'VVV";
    setup.SubstituteApiVersionInUrl = true;
});

Теперь у нас есть настройка управления версиями API и все готово, давайте попробуем использовать ее для управления версиями контроллера.

Создайте 2 папки версии и папку Controller и создайте 2 пользовательских контроллера.

Чтобы реализовать управление версиями API в .NET, вы можете использовать такие атрибуты, как Route, чтобы указать конечную точку URL-адреса или заголовки для доступа к различным версиям вашего API. Например, вы можете использовать атрибут Route с параметром apiVersion, чтобы указать номер версии в конечной точке URL, например:

[Route("api/v{version:apiVersion}/[controller]")]This will allow you to access different versions of your API using the version number in the URL.

Кроме того, вы можете использовать атрибут Route без параметра apiVersion, чтобы указать конечную точку по умолчанию, и использовать заголовок x-api-version, чтобы указать версию API в запросах. Например:

[Route("api/[controller]")]

При таком подходе клиенты могут указывать версию API, которую они хотят использовать, используя заголовок x-api-version в своих запросах. Это может быть полезно, если вы хотите разрешить клиентам доступ к разным версиям вашего API, используя одну и ту же конечную точку.

В папке v1 Folder создайте пользовательский контроллер

using Microsoft.AspNetCore.Mvc;

namespace WebApiVersioningTest.Controllers.V1;


[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[Route("api/[controller]")]
[ApiVersion("1.0")]
public class UserController : ControllerBase
{


    [MapToApiVersion("1.0")]
    [HttpGet]
    public IActionResult Get()
    {
        return Ok("V1");
    }
}

В папке v2 Folder создайте контроллер User V2:

using Microsoft.AspNetCore.Mvc;

namespace WebApiVersioningTest.Controllers.V2;


[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[Route("api/[controller]")]
[ApiVersion("2.0")]
public class UserController : ControllerBase
{


    [MapToApiVersion("2.0")]
    [HttpGet]
    public IActionResult Get()
    {
        return Ok("V2");
    }
}

Конфигурация управления версиями Swagger

Чтобы настроить Swagger для работы с различными версиями API в .NET, вы можете реализовать интерфейс IConfigureNamedOptions<SwaggerGenOptions> и использовать его для регистрации каждой версии API и определения версии по умолчанию. Это можно сделать, создав класс ConfigureSwaggerOptions, который реализует метод Configure и интерфейс IConfigureNamedOptions<SwaggerGenOptions>, например:

public class ConfigureSwaggerOptions
    : IConfigureNamedOptions<SwaggerGenOptions>
{
    private readonly IApiVersionDescriptionProvider _provider;

    public ConfigureSwaggerOptions(
        IApiVersionDescriptionProvider provider)
    {
        _provider = provider;
    }

    /// <summary>
    /// Configure each API discovered for Swagger Documentation
    /// </summary>
    /// <param name="options"></param>
    public void Configure(SwaggerGenOptions options)
    {
        // add swagger document for every API version discovered
        foreach (var description in _provider.ApiVersionDescriptions)
        {
            options.SwaggerDoc(
                description.GroupName,
                CreateVersionInfo(description));
        }
    }

    /// <summary>
    /// Configure Swagger Options. Inherited from the Interface
    /// </summary>
    /// <param name="name"></param>
    /// <param name="options"></param>
    public void Configure(string name, SwaggerGenOptions options)
    {
        Configure(options);
    }

    /// <summary>
    /// Create information about the version of the API
    /// </summary>
    /// <param name="description"></param>
    /// <returns>Information about the API</returns>
    private OpenApiInfo CreateVersionInfo(
            ApiVersionDescription desc)
    {
        var info = new OpenApiInfo()
        {
            Title = ".NET Core (.NET 6) Web API",
            Version = desc.ApiVersion.ToString()
        };

        if (desc.IsDeprecated)
        {
            info.Description += " This API version has been deprecated. Please use one of the new APIs available from the explorer.";
        }

        return info;
    }
}

После создания этого класса вы можете добавить следующий код в свой файл Program.cs, чтобы использовать его для настройки Swagger:

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    var apiVersionDescriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();

    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
        {
            options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json",
                description.GroupName.ToUpperInvariant());
        }
    });
}

После реализации этого кода пользовательский интерфейс Swagger должен отображать документацию для каждой версии API. Это может быть полезно для предоставления потребителям API информации о различных версиях API и для тестирования разных версий API.

Таким образом, существует несколько разных подходов к управлению версиями REST API в .NET, каждый из которых имеет свои плюсы и минусы. Лучший подход для вашей ситуации будет зависеть от конкретных требований вашего API и предпочтений вашей команды. Важно тщательно рассмотреть все варианты и выбрать подход, который лучше всего подойдет для вашей ситуации.

Полный код этого проекта можно найти в следующем репозитории: https://github.com/saideldah/api-versioining-dot-net-6