API-versionering och dokumentation

Inget API är statiskt. Krav ändras, buggar hittas, nya finesser ska in. Utan en plan för hur du versionerar och dokumenterar API:et känner sig klienterna lika vilsna som turister utan karta. Här får du en tydlig strategi för att växa utan att bryta allt.

TL;DR

  • Ha en tydlig versioneringsstrategi från start (URL, header eller media type).
  • Kommunicera förändringar via dokumentation, changelog och deprecation-notiser.
  • Automatisera dokumentationen – Swagger/NSwag räddar dig från manuella PDF-äventyr.

Efter den här guiden kan du

  • Välja versioneringsstrategi som passar din miljö.
  • Implementera versionering i ASP.NET Core (via paketet Microsoft.AspNetCore.Mvc.Versioning).
  • Hålla dokumentationen uppdaterad med Swagger (OpenAPI) och skapa tydliga release-notiser.
  • Hantera övergångar mellan versioner utan att göra klienterna tokiga.

Strategier för versionering

MetodExempelFördelarNackdelar
URL/api/v1/ordersSynligt, enkelt att cache:aSvårt att hålla URL:er snygga över tid
Query parameter/api/orders?api-version=1Lätt att börja medRisk att caches missar att skilja versioner
Headerapi-version: 1.0Håller URL:er rena, flexibelKlienten måste minnas att skicka headern
Media typeAccept: application/json;v=1Bra för avancerade kontraktLite mer boilerplate både klient/server

Tips: Var konsekvent. Att blanda flera strategier är som att ha tre olika fjärrkontroller för samma TV.

Konfiguera versionering i ASP.NET Core

dotnet add package Microsoft.AspNetCore.Mvc.Versioning
builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.ReportApiVersions = true; // skickar tillbaka "api-supported-versions" headern
});

Skapa controllers med version-attribut:

[ApiController]
[Route("api/v{version:apiVersion}/orders")]
[ApiVersion("1.0")]
public class OrdersControllerV1 : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok(new { message = "V1 – enklaste orderlistan" });
}

[ApiController]
[Route("api/v{version:apiVersion}/orders")]
[ApiVersion("2.0")]
public class OrdersControllerV2 : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok(new { message = "V2 – nu med filtrering" });
}

ReportApiVersions = true ger klienten headers som api-supported-versions: 1.0, 2.0. Gulligt sätt att säga “det här stöder vi”.

Deprecation – säg till i tid

  • Använd HTTP-headern api-deprecated-versions eller egna Warning-headers.
  • Lägg in deadlines i dokumentationen: “V1 stöds tills 2025-12-31”.
  • Logga så fort någon träffar en gammal version. Då vet du vilka kunder du ska ringa.
public class DeprecationHeaderMiddleware
{
    private readonly RequestDelegate _next;

    public DeprecationHeaderMiddleware(RequestDelegate next) => _next = next;

    public async Task Invoke(HttpContext context)
    {
        await _next(context);

        if (context.GetRequestedApiVersion()?.MajorVersion == 1)
        {
            context.Response.Headers.Add(
                "Warning",
                "299 api.example.local \"API v1 utgår 2025-12-31. Uppgradera till v2.\"");
        }
    }
}

Registrera middleware direkt efter UseRouting().

Dokumentation som lever

Swagger / OpenAPI

dotnet add package Swashbuckle.AspNetCore
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo { Title = "Order API", Version = "v1" });
    options.SwaggerDoc("v2", new OpenApiInfo { Title = "Order API", Version = "v2" });
    options.DocInclusionPredicate((version, desc) =>
    {
        var apiVersion = desc.ActionDescriptor.EndpointMetadata
            .OfType<ApiVersionAttribute>()
            .SelectMany(attr => attr.Versions);
        return apiVersion.Any(v => $"v{v.ToString()}" == version);
    });
});

Kör app.UseSwagger(); app.UseSwaggerUI(); och du får två flikar: v1 och v2. Perfekt för att visa vad som förändrats.

Changelog och release notes

  • För protokoll över ändringar i en CHANGELOG.md – gärna med rubrikerna Added, Changed, Fixed.
  • Skicka ut e-post (eller Teams/Discord) vid brytande ändringar.
  • Lägg en “Breaking changes” ruta högst upp i dokumentationen. Klienter älskar att bli förvarnade.

Testa flera versioner samtidigt

  • Skriv integrationstester per version: GetV1_ReturnsLegacyFormat, GetV2_ReturnsPaginatedResult.
  • Använd Postman-kollektioner eller REST Client scripts (.http filer) för att pingla varje version i CI.
  • Kontrollera att nya controllers inte råkar råka registrera sig på fel route.

Checklista innan du släpper en ny version

  1. Finns dokumentation (Swagger + prose) för nya endpoints?
  2. Är changelog uppdaterad med tydlig rubrik?
  3. Skickades deprecation-notis till konsumenterna?
  4. Har vi regressionstester för gamla versioner?
  5. Är livscykeln bestämd (lanseringsdatum + sista stöd-datum)?

Sammanfattning

  • Planera hur du versionerar redan när API:t är nytt.
  • Automatisera dokumentation så långt det går – mindre risk att glömma.
  • Kommunicera förändringar som en väderrapport: ofta och utan drama.
  • Stäng inte av gamla versioner utan statistik – logga hur de används.

Dad joke

Varför gick version 1 i pension?

Den ville leva ett RESTfullt liv.


Upp

Upp


Licens: Apache 2.0 | © 2023 Marcus Medina, Campus Mölndal. Alla rättigheter förbehållna.
Du får använda och modifiera detta verk enligt villkoren i Apache License, Version 2.0. Du får inte använda detta verk för kommersiella ändamål utan tillstånd från upphovsmannen.