Hi,
I'm currently working on a micro services architecture, with multiple small web api applications. More or less one micro service per main resource. The micro services are hosted within Azure Service Fabric.
However I don't want to expose my internal architecture to my consumers from the big bad outside world. So I expose those micro services via an api gateway.
I use Swashbuckle to generate the swagger documents, for each web api exposed by the micro services. I think this is the right responsibility at the right place. However, it would be nice if I could host a combined swagger document in the api gateway. Would that be something that is a nice addition to Swashbuckle?
Thinking about this a bit more in detail, I think the easiest approach would be just some json merge for the following properties into a new swagger specification.
I don't think implementations like this should be part of swashbuckle, sounds like it would be polution to the existing functionality. What do you think?
Swashbuckle currently comprises 3 separate components that can be used together or independently depending on your needs:
For your Microservices infrastructure you could use a combination of these and a custom ISwaggerProvider to implement what you need.
Each Microservice would install Swashbuckle.Swagger and Swashbuckle.SwaggerGen to generate and expose Swagger JSON.
Then, in a dedicated "documentation" application, you could install Swashbuckle.Swagger and Swashbuckle.SwaggerUi. Here, you'll need to register an implementation of ISwaggerProvider with the IoC container for this to work. This would be your own custom implementation which makes remote calls to obtain the Swagger JSON from each Microservice and then combines them (i.e. JSON merge) to produce an uber Swagger document. If you configure everything correctly, the custom implementation of ISwaggerProvider should be the only significant lines of code you'd have to write
Hello @domaindrivendev , can I find some example of implementation of ISwaggerProvider with combines Json documents? Or any suggestion. Thanks
@Marusyk, were you able to achieve this? We are also developing our APIs as microservices, and each API is in a separate project. I am able to export my specs during build (using NSwag) however I'm now tasked with being able to combine my specs into a master file to serve with ReDoc. I only want to pull operations from one spec file into another master spec file.
Hi @EspressoBeans,
Yeah, we are using Swashbuckle with Ocelot API gateway.
Each microservice has installed only Swashbuckle.AspNetCore.SwaggerGen to generate and expose Swagger JSON.
The API gateway knows about other services, so we need to just grab their swagger jsons.
API gateway project has installed only the Swashbuckle.AspNetCore.SwaggerUI package.
At the end we can find out swagger of user service by http://gateway.com/users/swagger
Here are some code:
It each microservice:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "User service", Version = "v1" });
c.CustomSchemaIds(schema => schema.FullName);
});
and
app.UseSwagger(options =>
{
options.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.BasePath = "/users");
options.RouteTemplate = "/{documentName}/swagger.json";
});
in API gateway
app.UseSwaggerUI(setup =>
{
setup.RoutePrefix = "docs";
foreach (var service in configuration.Get<FileConfiguration>().ReRoutes) <-- here we get all route to internal services
{
var address = service.DownstreamHostAndPorts.First(); <-- like: https://localhost:3322
var url = $"{service.DownstreamScheme}://{address.Host}:{address.Port}/v1/swagger.json"; <-- get actual url to service swagger json
var jsonEndpoint = $"/{service.Key}/v1/swagger.json"; <-- service.Key is name of sevice from route, so we got url to json of service through gateway
app.Map(jsonEndpoint, b => <-- create endpoint to each service like: http://gateway.com/users/v1/swagger.json
{
b.Run(async x =>
{
string content = await _httpClient.GetStringAsync(url); <-- read json of service by url https://localhost:3322/v1/swagger.json
await x.Response.WriteAsync(content);
});
});
setup.SwaggerEndpoint(jsonEndpoint, service.Key);
}
});
Also I've attached the example of file with gateway configuration.
Hope this will help. Let me know if you need more details.
Most helpful comment
Hello @domaindrivendev , can I find some example of implementation of ISwaggerProvider with combines Json documents? Or any suggestion. Thanks