如何用Swashbuckle聚合多API端点为单个Swagger文档并通过网关代理?
Hey there! Let's walk through how to aggregate multiple API endpoints into a single Swagger document using Swashbuckle, while ensuring all requests go through your gateway proxy. I've broken this down into actionable steps that should cover your needs:
1. Configure Swashbuckle to Aggregate Remote Swagger Documents
First, each of your individual APIs needs to generate its own Swagger JSON (via Swashbuckle). Then your gateway will pull these JSON files and merge them into one unified document.
Step 1: Setup Swashbuckle on Individual APIs
Make sure every API exposes its Swagger JSON at a standard endpoint (e.g.,/swagger/v1/swagger.json). For each API, set a uniqueTitleandVersionin their Swashbuckle config to avoid naming conflicts during merging:services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "User Service API", Version = "v1" }); });Step 2: Pull & Merge Documents in the Gateway
InstallSwashbuckle.AspNetCorein your gateway project, then configure the Swagger generator to reference remote API documents. You can use the built-inRemoteReferencemethod, or manually fetch and merge for more control:services.AddSwaggerGen(c => { // Define your gateway's own Swagger doc (if it has local endpoints) c.SwaggerDoc("aggregated", new OpenApiInfo { Title = "Aggregated Gateway API", Version = "v1" }); // Add references to remote API Swagger docs c.RemoteReference("user-service", "https://user-service.example.com/swagger/v1/swagger.json"); c.RemoteReference("order-service", "https://order-service.example.com/swagger/v1/swagger.json"); // Resolve schema name conflicts by using full type names c.CustomSchemaIds(type => type.FullName?.Replace(".", "_") ?? type.Name); });If you need more flexibility (like modifying paths before merging), you can manually fetch each Swagger JSON via
HttpClient, parse it into anOpenApiDocument, then merge paths/schemas into the gateway's document.
2. Configure Gateway Proxy Routing
Next, ensure all API requests are routed through your gateway. Below is an example using YARP (a popular .NET reverse proxy), but the logic applies to other gateways like Ocelot too.
Setup Routing Rules
Add route configurations to your gateway'sappsettings.jsonto map gateway paths to backend APIs:"ReverseProxy": { "Routes": { "user-service-route": { "ClusterId": "user-service-cluster", "Match": { "Path": "/user-service/{**catch-all}" } }, "order-service-route": { "ClusterId": "order-service-cluster", "Match": { "Path": "/order-service/{**catch-all}" } } }, "Clusters": { "user-service-cluster": { "Destinations": { "user-service": { "Address": "https://user-service.example.com/" } } }, "order-service-cluster": { "Destinations": { "order-service": { "Address": "https://order-service.example.com/" } } } } }Adjust Swagger Paths to Match Gateway Routes
The remote API's original paths (e.g.,/api/users) need to be prefixed with the gateway's route path (e.g.,/user-service/api/users). Use aDocumentFilterto modify paths during Swagger generation:public class PathPrefixFilter : IDocumentFilter { private readonly string _prefix; public PathPrefixFilter(string prefix) => _prefix = prefix; public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) { var updatedPaths = new OpenApiPaths(); foreach (var (pathKey, pathItem) in swaggerDoc.Paths) { updatedPaths.Add(_prefix + pathKey, pathItem); } swaggerDoc.Paths = updatedPaths; } }Register this filter for each remote API in your gateway's Swashbuckle config:
c.DocumentFilter<PathPrefixFilter>("/user-service"); // Prefix for user service paths c.DocumentFilter<PathPrefixFilter>("/order-service"); // Prefix for order service paths
3. Handle Authentication & Authorization
If your APIs use authentication (e.g., JWT), ensure the gateway handles it uniformly and passes credentials to backend services.
Configure Swagger UI for Authentication
Enable OAuth/JWT support in the gateway's Swagger UI so users can authenticate and send valid requests:app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/aggregated/swagger.json", "Aggregated Gateway API"); c.OAuthClientId("your-gateway-client-id"); c.OAuthAppName("Gateway Aggregated API"); c.OAuthUsePkce(); });Forward Authentication Headers
Configure your gateway proxy to forward theAuthorizationheader (or other auth headers) to backend APIs. For YARP, this is enabled by default, but double-check your proxy settings to ensure headers aren't stripped.
4. Test & Debug
- Start all backend APIs and the gateway, then visit the gateway's Swagger UI (typically at
/swagger). You should see all aggregated endpoints from every API. - Test each endpoint to confirm requests are routed correctly through the gateway and return valid responses.
- If you hit schema name conflicts, tweak the
CustomSchemaIdslogic to ensure unique names for all models across APIs.
内容的提问来源于stack exchange,提问作者Gayan

