I have a AspNetZero .NetCore + Angular project and I need to implement api versioning to the project for backwards compatibility. I followed a few examples online, but they either don't specify all the steps, or are specific to mvc, and this project uses the AppService pattern. If any one has successfully managed to implement api versioning in a AspNetZero project, I would really appreciate your help.
I'm currently at the swagger page showing two version, but for v1, I get an AmbiguousMatchException and for v2 swagger can't find the v2 file, so I assume it's not getting generated.
In my Application project, I changed the current AppService's namespace to .v1, and created a new AppService with namespace v2, that inherits the old one, and overrides 1 method which will be the v2.
The aim is to be able to call both methods once it's done with i.e: (http://localhost:9901/api/services/app/Equities/Get_Snapshot or http://localhost:9901/api/services/v1/Equities/Get_Snapshot) and http://localhost:9901/api/services/v2/Equities/Get_Snapshot
Open Startup.cs
in YOURCOMPANY.Web.Host
project.
In the ConfigureServices
method, scroll down and find services.AddSwaggerGen ...
Implement the following code:
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo()
{
Title = "MY API",
Version = "v1",
Description = "Any description for your V1 APIs."
});
options.SwaggerDoc("public", new OpenApiInfo()
{
Title = "CMS API",
Version = "v2",
Description = "Any description for your V2 APIs."
});
options.DocInclusionPredicate((docName, apiDesc) =>
{
switch (docName)
{
case "v1":
return true;
case "v2":
return apiDesc.GroupName == null || apiDesc.GroupName == "v2";
default:
return false;
}
});
options.ParameterFilter<SwaggerEnumParameterFilter>();
options.SchemaFilter<SwaggerEnumSchemaFilter>();
options.OperationFilter<SwaggerOperationIdFilter>();
options.OperationFilter<SwaggerOperationFilter>();
options.CustomDefaultSchemaIdSelector();
}).AddSwaggerGenNewtonsoftSupport();
Next, in the Configure
method, scroll down and find app.UseSwaggerUI ...
Open appsettings.json
in YOURCOMPANY.Web.Host
and add a new endpoint configuration variable in the "App"
field:
"SwaggerEndPoint": "/swagger/v1/swagger.json",
"SwaggerV2EndPoint": "/swagger/v2/swagger.json"
Implement the following code:
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint(_appConfiguration["App:SwaggerEndPoint"], "MY API V1");
options.SwaggerEndpoint(_appConfiguration["App:SwaggerPublicEndPoint"], "MY API V2");
options.IndexStream = () => Assembly.GetExecutingAssembly()
.GetManifestResourceStream("YOURCOMPANY.Web.wwwroot.swagger.ui.index.html");
options.InjectBaseUrl(_appConfiguration["App:ServerRootAddress"]);
});
Now you can implement APIs in V2
group by adding ApiExplorerSettings
attribute in your YOURCOMPANY.Application
project; let's assume you have a service named (TestAppService),
Then implement your methods (APIs) in the below namespace, and simply open your Swagger UI and test it.
namespace CMS.TestNameSpace
{
[ApiExplorerSettings(GroupName = "v2")]
[Route("api/[controller]/[action]")]
public class TestAppService : (YOUR)AppServiceBase, ITestAppService
{
[HttpGet]
public async Task<TestDto> GetTest(TestDtoInput input)
{
}
}
}