Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Phiên bản & Tài liệu

API Versioning

Cài đặt

dotnet add package Microsoft.AspNetCore.Mvc.Versioning

Cấu hình

// Program.cs
builder.Services.AddApiVersioning(options =>
{
    options.DefaultApiVersion = new ApiVersion(1, 0);
    options.AssumeDefaultVersionWhenUnspecified = true;
    options.ReportApiVersions = true;
    options.ApiVersionReader = ApiVersionReader.Combine(
        new UrlSegmentApiVersionReader(),
        new HeaderApiVersionReader("X-Api-Version"),
        new QueryStringApiVersionReader("v"));
});

Versioning Strategies

1. URL Path (phổ biến nhất)

[ApiVersion("1.0")]
[ApiVersion("2.0")]
[Route("api/v{v:apiVersion}/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    [MapToApiVersion("1.0")]
    public IActionResult GetV1() => Ok(new { version = "1.0" });
    
    [HttpGet]
    [MapToApiVersion("2.0")]
    public IActionResult GetV2() => Ok(new { version = "2.0", extra = "data" });
}

2. Query String

GET /api/products?api-version=1.0
GET /api/products?api-version=2.0

3. Header

GET /api/products
X-Api-Version: 1.0

Deprecation

[ApiVersion("1.0")]
[ApiVersion("2.0", Deprecated = true)] // Mark as deprecated
[Route("api/v{v:apiVersion}/[controller]")]
public class ProductsController : ControllerBase { }

Swagger/OpenAPI

Cài đặt

dotnet add package Swashbuckle.AspNetCore

Cấu hình

// Program.cs
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "My API",
        Version = "v1",
        Description = "API Description",
        Contact = new OpenApiContact
        {
            Name = "Support",
            Email = "support@example.com"
        }
    });
    
    // Add JWT Authentication to Swagger
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "JWT Authorization header using the Bearer scheme",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Bearer"
    });
    
    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty<string>()
        }
    });
});

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API v1");
    c.RoutePrefix = "swagger"; // Access at /swagger
});

XML Documentation

// Program.cs
builder.Services.AddSwaggerGen(c =>
{
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath);
});

/// <summary>
/// Get all products
/// </summary>
/// <param name="category">Filter by category</param>
/// <returns>List of products</returns>
[HttpGet]
[ProducesResponseType(typeof(List<Product>), 200)]
[ProducesResponseType(400)]
public IActionResult GetProducts([FromQuery] string category) { }

Swagger Response Attributes

[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public IActionResult Create([FromBody] Product product)
{
    // ...
}

Best Practices cho API Versioning

1. Chọn chiến lược version phù hợp

StrategyProsCons
URL PathRõ ràng, dễ debugPhải update client URLs
Query StringKhông thay đổi URLÍt visible
HeaderLinh hoạtKhó debug

2. Support backwards compatibility

// ✅ Tốt - Add new fields, không break old
public class ProductResponse
{
    public int Id { get; set; }
    public string Name { get; set; }
    // New in v2
    public string Description { get; set; } 
}

// ❌ Tránh - Breaking changes
// - Remove fields
// - Change field types
// - Change validation rules

3. Document changes

# OpenAPI spec
components:
  schemas:
    ProductV1:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
    ProductV2:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:  # New field
          type: string

4. Deprecation policy

  • Thông báo deprecation trước khi remove
  • Sử dụng HTTP headers để warning
  • Cung cấp migration guide