理解多版本兼容的需求
Web API 版本兼容的必要性:業(yè)務(wù)迭代、客戶端適配、接口演進時的平滑過渡。常見場景包括新增字段、廢棄舊接口、重構(gòu)參數(shù)結(jié)構(gòu)等。
版本控制實現(xiàn)方式
URL 路徑版本控制
在路由中嵌入版本號(如 api/v1/products),通過路由配置或特性標記實現(xiàn)。
查詢字符串版本控制
通過 URL 參數(shù)傳遞版本(如 api/products?version=1),靈活但需手動解析。
請求頭版本控制
利用 Accept 或自定義頭(如 X-API-Version)傳遞版本,無侵入性但需客戶端配合。
具體實現(xiàn)可參考NetCoreKevin中的Kevin.Api.Versioning模塊
一個基于NET8搭建DDD-微服務(wù)-現(xiàn)代化Saas企業(yè)級WebAPI前后端分離架構(gòu):前端Vue3、IDS4單點登錄、多級緩存、自動任務(wù)、分布式、AI智能體、一庫多租戶、日志、授權(quán)和鑒權(quán)、CAP事件、SignalR、領(lǐng)域事件、MCP協(xié)議服務(wù)、IOC模塊化注入、Cors、Quartz自動任務(wù)、多短信、AI、AgentFramework、SemanticKernel集成、RAG檢索增強+Qdrant矢量數(shù)據(jù)庫、OCR識別、API多版本、單元測試、RabbitMQ
項目地址:github:https://github.com/junkai-li/NetCoreKevin
Gitee: https://gitee.com/netkevin-li/NetCoreKevin
多版本代碼組織策略
文件夾分層
按版本號劃分目錄(如 Controllers/V1/ProductController.cs),物理隔離但可能重復(fù)代碼。
條件邏輯分支
同一控制器內(nèi)通過 if-else 或策略模式處理不同版本,適合差異較小的場景。
抽象基類與繼承
公共邏輯提取到基類,派生類實現(xiàn)版本差異,平衡復(fù)用與隔離。
版本切換與路由配置
使用 IApiVersionReader 配置版本讀取方式(如 HeaderApiVersionReader)。
示例代碼:
var apiVersioningBuilder = services.AddApiVersioning(options =>
{
//通過Header向客戶端通報支持的版本
options.ReportApiVersions = true;
//允許不加版本標記直接調(diào)用接口
options.AssumeDefaultVersionWhenUnspecified = true;
//接口默認版本
//options.DefaultApiVersion = new ApiVersion(1, 0);
//如果未加版本標記默認以當前最高版本進行處理
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
// 結(jié)合多種版本控制方式
options.ApiVersionReader = ApiVersionReader.Combine(
new QueryStringApiVersionReader("version"),
new UrlSegmentApiVersionReader(),
new HeaderApiVersionReader("X-API-Version"),
new MediaTypeApiVersionReader("version")
);
});
apiVersioningBuilder.AddApiExplorer(options =>
{
// add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
// note: the specified format code will format the version as "'v'major[.minor][-status]"
options.GroupNameFormat = "'v'VVV";
// note: this option is only necessary when versioning by url segment. the SubstitutionFormat
// can also be used to control the format of the API version in route templates
options.SubstituteApiVersionInUrl = true;
});
版本廢棄與兼容處理
標記過時版本:
[ApiVersion("1.0", Deprecated = true)]
public class ProductV1Controller : ControllerBase { ... }
新增SwaggerOperationFilter:
public class SwaggerOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var apiDescription = context.ApiDescription;
//判斷接口遺棄狀態(tài),對接口進行標記調(diào)整
operation.Deprecated |= apiDescription.IsDeprecated();
if (operation.Parameters == null)
{
return;
}
//為 api-version 參數(shù)添加必填驗證
foreach (var parameter in operation.Parameters)
{
var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
if (parameter.Description == null)
{
parameter.Description = description.ModelMetadata?.Description;
}
if (parameter.Schema.Default == null && description.DefaultValue != null)
{
parameter.Schema.Default = new OpenApiString(description.DefaultValue.ToString());
}
parameter.Required |= description.IsRequired;
}
}
}
通過 Sunset 響應(yīng)頭通知客戶端廢棄時間,并提供遷移文檔。
測試與文檔化
單元測試覆蓋不同版本邏輯,確保兼容性。
使用 Swagger 或 OpenAPI 生成多版本文檔,標注版本差異。
性能與維護權(quán)衡
緩存策略減少版本判斷開銷,避免過度設(shè)計。
制定版本生命周期規(guī)則(如支持 N-2 版本)。
案例分析
對比電商平臺訂單接口的演進:V1 僅基礎(chǔ)字段,V2 增加優(yōu)惠券邏輯,V3 引入分頁重構(gòu)。