Skip to main content

version-http-apis

Add API versioning to ABP HTTP APIs so multiple versions of the same service coexist behind static client proxies. USE FOR: AddAbpApiVersioning, query/header/media-type version readers, attaching ApiVersions to conventional controllers, ICurrentApiVersionInfo runtime version switching, the versioned API explorer. DO NOT USE FOR: exposing services as controllers in the first place (use expose-http-apis); Swagger UI / OpenAPI doc setup (use configure-swagger-openapi); generating or calling C# client proxies (use consume-remote-services).

Informations de source

Dépôt
abpframework/abp-skills
Dernière activité de la source
20 juillet 2026 à 03:24
Langue détectée de SKILL.md
anglais
Étoiles
23
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
version-http-apis
description
Add API versioning to ABP HTTP APIs so multiple versions of the same service coexist behind static client proxies. USE FOR: AddAbpApiVersioning, query/header/media-type version readers, attaching ApiVersions to conventional controllers, ICurrentApiVersionInfo runtime version switching, the versioned API explorer. DO NOT USE FOR: exposing services as controllers in the first place (use expose-http-apis); Swagger UI / OpenAPI doc setup (use configure-swagger-openapi); generating or calling C# client proxies (use consume-remote-services).
license
MIT
# Version ABP HTTP APIs ABP integrates the [ASP.NET API Versioning](https://github.com/dotnet/aspnet-api-versioning/wiki) library and adapts it to Auto (Conventional) API Controllers and the static C# / JavaScript client proxies. You enable it once, then either attach versions per controller (attribute routing) or per assembly (conventional controllers). ## When to Use - Serving `1.0` and `2.0` (etc.) of the same service side by side. - Attaching versions to conventional controllers via `ConventionalControllers.Create(...)`. - Switching the requested version from C# at runtime with `ICurrentApiVersionInfo`. - Building one Swagger document per discovered version. ## When Not to Use - **Just exposing a service as a controller** (no versions yet) — use **expose-http-apis**. - **Swagger UI / OpenAPI wiring** beyond the versioned explorer — use **configure-swagger-openapi**. - **Generating or calling client proxies** — use **consume-remote-services**. ## ⚠️ Read this first: URL-path versioning breaks the static proxies The static C# and JavaScript client proxies **cannot** carry the version in the URL path/segment. Use **query-string versioning** (`?api-version=2.0`) — the default ABP proxies emit. Grounding: `ApiVersionInfo.ShouldSendInQueryString()` returns `!BindingSource.IsIn("Path")` (`framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ApiVersionInfo.cs`), so a `Path` binding source is never appended to the proxy request. The versioning doc says the same: this feature "does not compatible with URL Path Versioning, we suggest to use Versioning via the Query String" (`docs/en/framework/api-development/versioning.md`). ## Enable versioning `AddAbpApiVersioning` is an `IServiceCollection` extension in `Microsoft.Extensions.DependencyInjection` (`framework/src/Volo.Abp.AspNetCore.Mvc/.../AbpApiVersioningExtensions.cs`). Its signature: ```csharp IApiVersioningBuilder AddAbpApiVersioning( this IServiceCollection services, Action<ApiVersioningOptions>? apiVersioningOptionsSetupAction = null, Action<MvcApiVersioningOptions>? mvcApiVersioningOptionsSetupAction = null) ``` `ApiVersioningOptions` / `MvcApiVersioningOptions` and the properties set below (`ReportApiVersions`, `AssumeDefaultVersionWhenUnspecified`) come from the ASP.NET API Versioning library — they are **not** ABP types. Same for `IApiControllerFilter` / `NoControllerFilter` (used to keep neutral/versionless APIs visible). ```csharp public override void ConfigureServices(ServiceConfigurationContext context) { // Show neutral / versionless APIs. context.Services.AddTransient<IApiControllerFilter, NoControllerFilter>(); context.Services.AddAbpApiVersioning(options => { options.ReportApiVersions = true; options.AssumeDefaultVersionWhenUnspecified = true; }); Configure<AbpAspNetCoreMvcOptions>(options => { options.ChangeControllerModelApiExplorerGroupName = false; }); } ``` The version reader (query string vs. header vs. media type) is the standard ASP.NET API Versioning `ApiVersionReader` on `ApiVersioningOptions` — keep it on the query string when static proxies are in play (see the warning above). ## Attribute-routed controllers Put `[ApiVersion(...)]` (an ASP.NET API Versioning attribute) on each controller. Two controllers sharing one `[Route]` but different versions serve as v1/v2 of the same service: ```csharp [ApiVersion("1.0", Deprecated = true)] [ControllerName("Book")] [Route("api/BookStore/Book")] public class BookController : BookStoreController, IBookAppService { /* ... */ } [ApiVersion("2.0")] [ControllerName("Book")] [Route("api/BookStore/Book")] public class BookV2Controller : BookStoreController, IBookV2AppService { /* ... */ } ``` ## Conventional (Auto API) controllers Attach versions per assembly in `PreConfigureServices`. `ConventionalControllerSetting.ApiVersions` is a `List<ApiVersion>` (`framework/src/Volo.Abp.AspNetCore.Mvc/.../Conventions/ConventionalControllerSetting.cs`); `ApiVersion` is an ASP.NET API Versioning type. Use `TypePredicate` to split versions by namespace: ```csharp public override void PreConfigureServices(ServiceConfigurationContext context) { PreConfigure<AbpAspNetCoreMvcOptions>(options => { options.ConventionalControllers.Create(typeof(BookStoreWebAppModule).Assembly, opts => { opts.TypePredicate = t => t.Namespace == typeof(v2.TodoAppService).Namespace; opts.ApiVersions.Add(new ApiVersion(2, 0)); }); options.ConventionalControllers.Create(typeof(BookStoreWebAppModule).Assembly, opts => { opts.TypePredicate = t => t.Namespace == typeof(v1.TodoAppService).Namespace; opts.ApiVersions.Add(new ApiVersion(1, 0)); }); }); } ``` Then wire those pre-configured settings into the versioning options with the `ConfigureAbp` extension — `ConfigureAbp(this MvcApiVersioningOptions options, AbpAspNetCoreMvcOptions mvcOptions)` (same file as `AddAbpApiVersioning`). It reads `mvcOptions.ConventionalControllers`, calling each setting's `MvcApiVersioningConfigurer` if set, otherwise applying its `ApiVersions` by convention (neutral when none): ```csharp public override void ConfigureServices(ServiceConfigurationContext context) { var preActions = context.Services.GetPreConfigureActions<AbpAspNetCoreMvcOptions>(); context.Services.AddTransient<IApiControllerFilter, NoControllerFilter>(); context.Services.AddAbpApiVersioning(options => { options.ReportApiVersions = true; options.AssumeDefaultVersionWhenUnspecified = true; }, options => { options.ConfigureAbp(preActions.Configure()); }); } ``` ## Switch the requested version at runtime (C#) When one client wants a specific version from a multi-version service, inject `ICurrentApiVersionInfo` (`namespace Volo.Abp.Http.Client.ClientProxying`) and scope the change with `Change(...)`. It stores an `AsyncLocal` value restored on dispose, so wrap it in a `using`: ```csharp var current = serviceProvider.GetRequiredService<ICurrentApiVersionInfo>(); var bookService = serviceProvider.GetRequiredService<IBookV4AppService>(); using (current.Change(new ApiVersionInfo(ParameterBindingSources.Query, "4.0"))) { var book = await bookService.GetAsync(); // proxy adds ?api-version=4.0 } ``` - `ApiVersionInfo(string bindingSource, string version)` — `framework/src/Volo.Abp.Http.Client/.../ClientProxying/ApiVersionInfo.cs`. - `ParameterBindingSources.Query` / `.Header` / `.Path` … are string consts in `Volo.Abp.Http.ProxyScripting.Generators.ParameterBindingSources`. Use `Query`; `Path` is dropped by the proxy (see the warning). ## Versioned API explorer / Swagger Chain `.AddApiExplorer(...)` on the builder returned by `AddAbpApiVersioning` for one Swagger document per version, then iterate `provider.ApiVersionDescriptions` to add a `SwaggerEndpoint` each. `GroupNameFormat`, `SubstituteApiVersionInUrl`, `IApiVersionDescriptionProvider` are ASP.NET API Versioning types (not ABP); full example in the versioning doc. Deeper Swagger setup belongs to the **configure-swagger-openapi** skill. ## Validation - Call the same route with `?api-version=1.0` and `?api-version=2.0`; confirm each hits the matching version and that `ReportApiVersions` adds `api-supported-versions` response headers. - Confirm neutral/versionless endpoints still appear (that's the `NoControllerFilter` job). - With generated static proxies, confirm the request carries the version on the **query string**, not the path. ## Common Pitfalls - **URL-path/segment versioning silently breaks static proxies** — the proxy never sends a `Path` binding source. Stay on query-string versioning. - Setting `ApiVersions` on a conventional-controller assembly does nothing unless `options.ConfigureAbp(preActions.Configure())` is applied to the versioning options. - `AddAbpApiVersioning` returns an `IApiVersioningBuilder`; call `.AddApiExplorer(...)` on that return value — don't try to add the explorer separately. - `ReportApiVersions`, `AssumeDefaultVersionWhenUnspecified`, `[ApiVersion]`, `ApiVersion`, `IApiControllerFilter`/`NoControllerFilter` are ASP.NET API Versioning symbols ABP wraps — look them up in that library's wiki, not the ABP API.
Voir sur GitHub