{"id":19990094,"url":"https://github.com/burgyn/mmlib.swaggerforocelot","last_synced_at":"2025-05-14T07:08:24.308Z","repository":{"id":37951795,"uuid":"159215013","full_name":"Burgyn/MMLib.SwaggerForOcelot","owner":"Burgyn","description":"This repo contains swagger extension for ocelot.","archived":false,"fork":false,"pushed_at":"2025-04-07T17:49:58.000Z","size":753,"stargazers_count":363,"open_issues_count":30,"forks_count":97,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-11T18:48:59.827Z","etag":null,"topics":["api-gateway","dotnet","gateway","ocelot","swagger"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Burgyn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-11-26T18:32:50.000Z","updated_at":"2025-04-27T07:08:00.000Z","dependencies_parsed_at":"2023-02-15T12:15:57.591Z","dependency_job_id":"1fb27772-3b51-448c-bbb0-1ef56517f891","html_url":"https://github.com/Burgyn/MMLib.SwaggerForOcelot","commit_stats":{"total_commits":241,"total_committers":29,"mean_commits":8.310344827586206,"dds":0.3526970954356846,"last_synced_commit":"777cc8817be729ddef50d7d39891f3d16569ec13"},"previous_names":[],"tags_count":69,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Burgyn%2FMMLib.SwaggerForOcelot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Burgyn%2FMMLib.SwaggerForOcelot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Burgyn%2FMMLib.SwaggerForOcelot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Burgyn%2FMMLib.SwaggerForOcelot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Burgyn","download_url":"https://codeload.github.com/Burgyn/MMLib.SwaggerForOcelot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254092775,"owners_count":22013290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-gateway","dotnet","gateway","ocelot","swagger"],"created_at":"2024-11-13T04:50:59.027Z","updated_at":"2025-05-14T07:08:24.275Z","avatar_url":"https://github.com/Burgyn.png","language":"C#","funding_links":["https://www.buymeacoffee.com/minomartiniak"],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"./assets/logo.png\" alt=\"logo\" width=\"300\"/\u003e\n\n![Publish package](https://github.com/Burgyn/MMLib.SwaggerForOcelot/workflows/Publish%20package/badge.svg)\n\n**SwaggerForOcelot** combines two amazing projects **[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)** and **[Ocelot](https://github.com/ThreeMammals/Ocelot)**. Allows you to view and use swagger documentation for downstream services directly through the Ocelot project.\n\nDirect via `http://ocelotprojecturl:port/swagger` provides documentation for downstream services configured in `ocelot.json`. Additionally, the addresses are modified to match the `UpstreamPathTemplate` from the configuration.\n\n![SwaggerForOcelot](https://raw.githubusercontent.com/Burgyn/MMLib.SwaggerForOcelot/master/demo/image.png)\n\n---\nDid this project help you? You can now buy me a coffee ☕️. \n\n\u003ca href=\"https://www.buymeacoffee.com/minomartiniak\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-violet.png\" alt=\"Buy Me A Coffee\" style=\"height: 60px !important;width: 217px !important;\" \u003e\u003c/a\u003e\n\n## Get Started\n\n1. Configure SwaggerGen in your downstream services.\n   \u003e Follow the [SwashbuckleAspNetCore documentation](https://github.com/domaindrivendev/Swashbuckle.AspNetCore#getting-started).\n2. Install Nuget package into yout ASP.NET Core Ocelot project.\n   \u003e dotnet add package MMLib.SwaggerForOcelot\n3. Configure SwaggerForOcelot in `ocelot.json`.\n\n```Json\n {\n  \"Routes\": [\n    {\n      \"DownstreamPathTemplate\": \"/api/{everything}\",\n      \"DownstreamScheme\": \"http\",\n      \"DownstreamHostAndPorts\": [\n        {\n          \"Host\": \"localhost\",\n          \"Port\": 5100\n        }\n      ],\n      \"UpstreamPathTemplate\": \"/api/contacts/{everything}\",\n      \"UpstreamHttpMethod\": [ \"Get\" ],\n      \"SwaggerKey\": \"contacts\"\n    },\n    {\n      \"DownstreamPathTemplate\": \"/api/{everything}\",\n      \"DownstreamScheme\": \"http\",\n      \"DownstreamHostAndPorts\": [\n        {\n          \"Host\": \"localhost\",\n          \"Port\": 5200\n        }\n      ],\n      \"UpstreamPathTemplate\": \"/api/orders/{everything}\",\n      \"UpstreamHttpMethod\": [ \"Get\" ],\n      \"SwaggerKey\": \"orders\"\n    }\n  ],\n  \"SwaggerEndPoints\": [\n    {\n      \"Key\": \"contacts\",\n      \"Config\": [\n        {\n          \"Name\": \"Contacts API\",\n          \"Version\": \"v1\",\n          \"Url\": \"http://localhost:5100/swagger/v1/swagger.json\"\n        }\n      ]\n    },\n    {\n      \"Key\": \"orders\",\n      \"Config\": [\n        {\n          \"Name\": \"Orders API\",\n          \"Version\": \"v0.9\",\n          \"Url\": \"http://localhost:5200/swagger/v0.9/swagger.json\"\n        },\n        {\n          \"Name\": \"Orders API\",\n          \"Version\": \"v1\",\n          \"Url\": \"http://localhost:5200/swagger/v1/swagger.json\"\n        },\n        {\n          \"Name\": \"Orders API\",\n          \"Version\": \"v2\",\n          \"Url\": \"http://localhost:5200/swagger/v2/swagger.json\"\n        },\n        {\n          \"Name\": \"Orders API\",\n          \"Version\": \"v3\",\n          \"Url\": \"http://localhost:5200/swagger/v3/swagger.json\"\n        }\n      ]\n    }\n  ],\n  \"GlobalConfiguration\": {\n    \"BaseUrl\": \"http://localhost\"\n  }\n}\n```\n\n   \u003e `SwaggerEndPoint` is configuration for downstream service swagger generator endpoint. Property `Key` is used to pair with the Route configuration. `Name` is displayed in the combobox. `Url` is downstream service swagger generator endpoint.\n\n4. In the `ConfigureServices` method of `Startup.cs`, register the SwaggerForOcelot generator.\n\n```CSharp\nservices.AddSwaggerForOcelot(Configuration);\n```\n\n5. In `Configure` method, insert the `SwaggerForOcelot` middleware to expose interactive documentation.\n\n```CSharp\napp.UseSwaggerForOcelotUI(opt =\u003e {\n  opt.PathToSwaggerGenerator = \"/swagger/docs\";\n})\n```\n\n   You can optionally include headers that your Ocelot Gateway will send when requesting a swagger endpoint. This can be especially useful if your downstream microservices require contents from a header to authenticate.\n\n  ```CSharp\napp.UseSwaggerForOcelotUI(opt =\u003e {\n    opt.DownstreamSwaggerHeaders = new[]\n    {\n        new KeyValuePair\u003cstring, string\u003e(\"Auth-Key\", \"AuthValue\"),\n    };\n})\n  ```\n\n  After swagger for ocelot transforms the downstream swagger to the upstream swagger, you have the ability to alter the upstream swagger if you need to by setting the `ReConfigureUpstreamSwaggerJson` option or `ReConfigureUpstreamSwaggerJsonAsync` option for async methods.\n\n  ```CSharp\npublic string AlterUpstreamSwaggerJson(HttpContext context, string swaggerJson)\n{\n    var swagger = JObject.Parse(swaggerJson);\n    // ... alter upstream json\n    return swagger.ToString(Formatting.Indented);\n}\n\napp.UseSwaggerForOcelotUI(opt =\u003e {\n    opt.ReConfigureUpstreamSwaggerJson = AlterUpstreamSwaggerJson;\n})\n  ```\nYou can optionally customize the swagger server prior to calling the endpoints of the microservices as follows:\n```CSharp\napp.UseSwaggerForOcelotUI(opt =\u003e {\n    opt.ReConfigureUpstreamSwaggerJson = AlterUpstreamSwaggerJson;\n    opt.ServerOcelot = \"/siteName/apigateway\" ;\n})\n  ```\n\nYou can optionally customize SwaggerUI:\n```CSharp\napp.UseSwaggerForOcelotUI(opt =\u003e {\n    // swaggerForOcelot options\n}, uiOpt =\u003e {\n    //swaggerUI options\n    uiOpt.DocumentTitle = \"Gateway documentation\";\n})\n  ```\n\n6. Show your microservices interactive documentation.\n\n   \u003e `http://ocelotserviceurl/swagger`\n\n## Open API Servers\n\nIf you have multiple servers defined in the downstream service Open API documentation, or you use server templating and you want to use it on the gateway side as well, then you must explicitly enable it on the Swagger endpoint definition by setting property `TakeServersFromDownstreamService` to `true`.\n\n```json\n\"SwaggerEndPoints\": [\n    {\n      \"Key\": \"users\",\n      \"TakeServersFromDownstreamService\": true,\n      \"Config\": [\n        {\n          \"Name\": \"Users API\",\n          \"Version\": \"v1\",\n          \"Service\": {\n            \"Name\": \"users\",\n            \"Path\": \"/swagger/v1/swagger.json\"\n          }\n        }\n      ]\n    }\n]\n```\n\n\u003e ⚠ If you set `TakeServersFromDownstreamService` to `true`, then the server path is not used to transform the paths of individual endpoints.\n\n## Virtual directory\n\nIf you have a `downstream service` hosted in the virtual directory, you probably have a `DownstreamPathTemplate` starting with the name of this virtual directory `/virtualdirectory/api/{everything}`. In order to properly replace the paths, it is necessary to set the property route `\"Virtualdirectory\":\"/virtualdirectory\"`.\n\nExample:\n\n``` Json\n {\n  \"DownstreamPathTemplate\": \"/project/api/{everything}\",\n  \"DownstreamScheme\": \"http\",\n  \"DownstreamHostAndPorts\": [\n      {\n      \"Host\": \"localhost\",\n      \"Port\": 5100\n      }\n  ],\n  \"UpstreamPathTemplate\": \"/api/project/{everything}\",\n  \"UpstreamHttpMethod\": [ \"Get\" ],\n  \"SwaggerKey\": \"project\",\n  \"VirtualDirectory\":\"/project\"\n}\n```\n\n## Service discovery\n\nIf you use [Ocelot Service Discovery Provider](https://ocelot.readthedocs.io/en/latest/features/servicediscovery.html) to find the host and port for the downstream service, then you can use the same service name for swagger configuration.\n\n``` Json\n\"Routes\": [\n  {\n    \"DownstreamPathTemplate\": \"/api/{everything}\",\n    \"ServiceName\": \"projects\",\n    \"UpstreamPathTemplate\": \"/api/project/{everything}\",\n    \"SwaggerKey\": \"projects\",\n  }\n],\n \"SwaggerEndPoints\": [\n    {\n      \"Key\": \"projects\",\n      \"Config\": [\n        {\n          \"Name\": \"Projects API\",\n          \"Version\": \"v1\",\n          \"Service\": {\n            \"Name\": \"projects\",\n            \"Path\": \"/swagger/v1/swagger.json\"\n          }\n        }\n      ]\n    }\n  ],\n\n  \"GlobalConfiguration\": {\n    \"ServiceDiscoveryProvider\": {\n      \"Type\": \"AppConfiguration\",\n      \"PollingInterval\": 1000\n    }\n  }\n```\n\n## The Gateway documentation itself\n\nThere are several real scenarios when you need to have a controller directly in your gateway. For example: specific aggregation of results from multiple services / legacy part of your system / ...\n\nIf you need to, you can also add documentation.\n\n1. Allow `GenerateDocsForGatewayItSelf` option in configuration section.\n\n```CSharp\nservices.AddSwaggerForOcelot(Configuration,\n  (o) =\u003e\n  {\n      o.GenerateDocsForGatewayItSelf = true;\n  });\n```\n\nor you can provide more options for gateway itself documentation\n\n```CSharp\nservices.AddSwaggerForOcelot(Configuration,\n  (o) =\u003e\n  {\n      o.GenerateDocsDocsForGatewayItSelf(opt =\u003e\n      {\n          opt.FilePathsForXmlComments = { \"MyAPI.xml\" };\n          opt.GatewayDocsTitle = \"My Gateway\";\n          opt.GatewayDocsOpenApiInfo = new()\n          {\n             Title = \"My Gateway\",\n             Version = \"v1\",\n          };\n          opt.DocumentFilter\u003cMyDocumentFilter\u003e();\n          opt.AddSecurityDefinition(\"Bearer\", new OpenApiSecurityScheme()\n          {\n              Description = @\"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'\",\n              Name = \"Authorization\",\n              In = ParameterLocation.Header,\n              Type = SecuritySchemeType.ApiKey,\n              Scheme = \"Bearer\"\n          });\n          opt.AddSecurityRequirement(new OpenApiSecurityRequirement()\n          {\n              {\n                  new OpenApiSecurityScheme\n                  {\n                      Reference = new OpenApiReference\n                      {\n                          Type = ReferenceType.SecurityScheme,\n                          Id = \"Bearer\"\n                      },\n                      Scheme = \"oauth2\",\n                      Name = \"Bearer\",\n                      In = ParameterLocation.Header,\n                  },\n                  new List\u003cstring\u003e()\n              }\n          });\n      });\n  });\n```\n\n2. Use Swagger generator in `Configure` section.\n\n```csharp\napp.UseSwagger();\n```\n\n![ocelot docs](https://raw.githubusercontent.com/Burgyn/MMLib.SwaggerForOcelot/swaggerforocelot_v4.9.1/demo/ocelotdocs.png)\n\n## Documentation of Ocelot Aggregates\n\nYou are probably familiar with Ocelot great feature [***Request Aggregation***](https://ocelot.readthedocs.io/en/latest/features/requestaggregation.html). Request Aggregation allows you to easily add a new endpoint to the gateway that will aggregate the result from other existing endpoints.\nIf you use these aggregations, you would probably want to have these endpoints in the api documentation as well.\n\n📢 From version `3.0.0` you can use this package for generating documentation for Ocelot aggregates.\n\nIn `ConfigureServices` allow `GenerateDocsForAggregates` option.\n\n```CSharp\nservices.AddSwaggerForOcelot(Configuration,\n  (o) =\u003e\n  {\n      o.GenerateDocsForAggregates = true;\n  });\n```\n\nDocumentations of your aggregates will be available on custom page **Aggregates**.\n![aggregates docs](https://raw.githubusercontent.com/Burgyn/MMLib.SwaggerForOcelot/swaggerforocelot_v4.9.1/demo/aggregates.png)\n\nThe current implementation may not cover all scenarios *(I hope most of them)*, but there are several ways you can change the final documentation.\n\n### Custom description\n\nBy default, this package generate description from downstream documentation. If you want add custom description for your aggregate route, you can add description to `ocelot.json`.\n\n```json\n\"Aggregates\": [ \n  {\n    \"RouteKeys\": [\n      \"user\",\n      \"basket\"\n    ],\n    \"Description\": \"Custom description for this aggregate route.\",\n    \"Aggregator\": \"BasketAggregator\",\n    \"UpstreamPathTemplate\": \"/gateway/api/basketwithuser/{id}\"\n  }\n]\n```\n\n### Different parameter names\n\nIt is likely that you will have different parameter names in the downstream services that you are aggregating. For example, in the User service you will have the `{Id}` parameter, but in the Basket service the same parameter will be called `{BuyerId}`. In order for Ocelot aggregations to work, you must have parameters named the same in Ocelot configurations, but this will make it impossible to find the correct documentation.\n\nTherefore, you can help the configuration by setting parameter name map.\n\n```json\n{\n  \"DownstreamPathTemplate\": \"/api/basket/{id}\",\n  \"UpstreamPathTemplate\": \"/gateway/api/basket/{id}\",\n  \"ParametersMap\": {\n    \"id\": \"buyerId\"\n  },\n  \"ServiceName\": \"basket\",\n  \"SwaggerKey\": \"basket\",\n  \"Key\": \"basket\"\n}\n```\n\nProperty `ParametersMap` is map, where `key` *(first parameter)* is the name of parameter in Ocelot configuration and `value` *(second parameter)* is the name of parameter in downstream service.\n\n### Custom aggregator\n\nThe response documentation is generated according to the rules that Ocelot uses to compose the response from the aggregate. If you use your custom `IDefinedAggregator`, your result may be different. In this case you can use `AggregateResponseAttibute`.\n\n```CSharp\n[AggregateResponse(\"Basket with buyer and busket items.\", typeof(CustomResponse))]\npublic class BasketAggregator : IDefinedAggregator\n{\n    public async Task\u003cDownstreamResponse\u003e Aggregate(List\u003cHttpContext\u003e responses)\n    {\n        ...\n    }\n}\n```\n\n### Modifying the generated documentation\n\nIf you do not like the final documentation, you can modify it by defining your custom postprocessor.\n\n```CSharp\nservices.AddSwaggerForOcelot(Configuration,\n  (o) =\u003e\n  {\n      o.GenerateDocsForAggregates = true;\n      o.AggregateDocsGeneratorPostProcess = (aggregateRoute, routesDocs, pathItemDoc, documentation) =\u003e\n      {\n          if (aggregateRoute.UpstreamPathTemplate == \"/gateway/api/basketwithuser/{id}\")\n          {\n              pathItemDoc.Operations[OperationType.Get].Parameters.Add(new OpenApiParameter()\n              {\n                  Name = \"customParameter\",\n                  Schema = new OpenApiSchema() { Type = \"string\"},\n                  In = ParameterLocation.Header\n              });\n          }\n      };\n  });\n```\n\n### If none of this is enough\n\n🙏 Feel free to provide a PR with implementation of your scenario. You will probably help many others.\n\n## Merging configuration files\n\nOptionally you can use the Ocelot feature [Merging configuration files](https://ocelot.readthedocs.io/en/latest/features/configuration.html#merging-configuration-files) to load the apigateway configuration from multiple configuration files named as follows: `ocelot.exampleName.json`. To activate this feature you need to use the following extension:\n\n```CSharp\nWebHost.CreateDefaultBuilder(args)\n  .ConfigureAppConfiguration((hostingContext, config) =\u003e\n  {\n      config.AddOcelotWithSwaggerSupport();\n  })\n  .UseStartup\u003cStartup\u003e();\n```\n\nUsing this extension the swagger path settings must be in a file called: `ocelot.SwaggerEndPoints.json`. If instead you want to use another name for this file you could set the name as follows _(without the .json extension)_:\n\n```CSharp\nWebHost.CreateDefaultBuilder(args)\n  .ConfigureAppConfiguration((hostingContext, config) =\u003e\n  {\n     config.AddOcelotWithSwaggerSupport((o) =\u003e {\n       o.FileOfSwaggerEndPoints = \"ocelot.swagger\";\n     })\n  })\n  .UseStartup\u003cStartup\u003e();\n```\n\nOptionally you can put the configuration files in a folder, and for that you have to set the extension as follows:\n\n```CSharp\nWebHost.CreateDefaultBuilder(args)\n  .ConfigureAppConfiguration((hostingContext, config) =\u003e\n  {\n    config.AddOcelotWithSwaggerSupport((o) =\u003e {\n      o.Folder = \"Configuration\";\n    });\n  })\n  .UseStartup\u003cStartup\u003e();\n```\n\nOptionally you can also add configuration files with the format `ocelot.exampleName.json` per environment, to use this functionality you must configure the extension as follows:\n\n```CSharp\nWebHost.CreateDefaultBuilder(args)\n  .ConfigureAppConfiguration((hostingContext, config) =\u003e\n  {\n    config.AddOcelotWithSwaggerSupport((o) =\u003e {\n      o.Folder = \"Configuration\";\n      o.Environment = hostingContext.HostingEnvironment;\n    });\n  })\n  .UseStartup\u003cStartup\u003e();\n```\n\nTo save the primary Ocelot config file under a name other than `ocelot.json then use the following:\n\n```CSharp\nWebHost.CreateDefaultBuilder(args)\n  .ConfigureAppConfiguration((hostingContext, config) =\u003e\n  {\n    config.AddOcelotWithSwaggerSupport((o) =\u003e {\n      o.PrimaryOcelotConfigFile = \"myOcelot.json\";\n    });\n  })\n  .UseStartup\u003cStartup\u003e();\n```\n\n## Control downstream to swagger api\nWith the `ISwaggerDownstreamInterceptor` interface you are able to inject your own logic to control the downstream.\n\n1. In the ConfigureServices method of Startup.cs, register your downstream interceptor along with your other dependencies.\n```CSharp\nservices.AddSingleton\u003cISwaggerDownstreamInterceptor, PublishedDownstreamInterceptor\u003e();\nservices.AddSingleton\u003cISwaggerEndpointConfigurationRepository, DummySwaggerEndpointRepository\u003e();\n```\n\n2. In your downstream interceptor add your custom logic to control if the downstream should be done.\n```CSharp\npublic class PublishedDownstreamInterceptor : ISwaggerDownstreamInterceptor\n{\n    private readonly ISwaggerEndpointConfigurationRepository _endpointConfigurationRepository;\n\n    public PublishedDownstreamInterceptor(ISwaggerEndpointConfigurationRepository endpointConfigurationRepository)\n    {\n        _endpointConfigurationRepository = endpointConfigurationRepository;\n    }\n\n    public bool DoDownstreamSwaggerEndpoint(HttpContext httpContext, string version, SwaggerEndPointOptions endPoint)\n    {\n        var myEndpointConfiguration = _endpointConfigurationRepository.GetSwaggerEndpoint(endPoint, version);\n\n        if (!myEndpointConfiguration.IsPublished)\n        {\n            httpContext.Response.StatusCode = 404;\n            httpContext.Response.WriteAsync(\"This enpoint is under development, please come back later.\");\n        }\n\n        return myEndpointConfiguration.IsPublished;\n    }\n}\n```\n\nNote, the service is still visible in the swagger ui the response is only visible in the request to the downstream url.\nIf you want to control the visibility of the endpoints as well you have to implement a custom swagger ui.\n\n## Security definition generation\n\nIt is possible to generate security definitions for the enpoints based on Ocelot configuration\n\n1. Add `AuthenticationOptions` to your route definition\n``` Json\n\"Routes\": [\n  {\n    \"DownstreamPathTemplate\": \"/api/{everything}\",\n    \"ServiceName\": \"projects\",\n    \"UpstreamPathTemplate\": \"/api/project/{everything}\",\n    \"SwaggerKey\": \"projects\",\n    \"AuthenticationOptions\": {\n      \"AuthenticationProviderKey\": \"Bearer\",\n      \"AllowedScopes\": [ \"scope\" ]\n    },\n  }\n]\n```\n\n2. Provide a mapping in Startup between `AuthenticationProviderKey` and it's corresponding `securityDefintion`\n```CSharp\nservices.AddSwaggerForOcelot(Configuration,\n  (o) =\u003e\n  {\n    o.AddAuthenticationProviderKeyMapping(\"Bearer\", \"appAuth\");\n  });\n```\n\n3. Now you should have security definitions on your swagger documents\n``` Json\n{\n  \"paths\": {\n    \"/api/project\": {\n      \"get\": {\n        ...\n        \"security\": [\n          {\n            \"appAuth\": [ \"scope\" ]\n          }\n        ]\n      }\n    }\n  }\n}\n```\n\nNote, this does not affect nor checks the swagger document's `securityDefinitions` property.\n\n## Downstream Documentation Caching\nIf your downstream documentation is too large, the response time may be slow. \nTo address this issue, you can enable caching of transformed documentation by setting the \n`DownstreamDocsCacheExpire` parameter. If this parameter is not provided, the documentation won't be cached.\nIf there is any change in the downstream documentation, the cache will be refreshed.\n\n```csharp\nservices.AddSwaggerForOcelot(Configuration,\n            setup =\u003e\n            {\n                setup.DownstreamDocsCacheExpire = TimeSpan.FromMinutes(10);\n            });\n```\n\n## Limitation\n\n- Now, this library support only `{everything}` as a wildcard in routing definition. #68\n- This package unfortunately does not support parameter translating between upstream and downstream path template. #59\n- If your downstream documentation is too large (usually more than 10 MB), the response may be too slow. You can turn off the removal of an unused schema component from downstream documentation by using `RemoveUnusedComponentsFromScheme: false`.\n```csharp\n \"SwaggerEndPoints\": [\n    {\n      \"Key\": \"projects\",\n      \"RemoveUnusedComponentsFromScheme\": false,\n      \"Config\": [\n        {\n          \"Name\": \"Projects API\",\n          \"Version\": \"v1\",\n          \"Service\": {\n            \"Name\": \"projects\",\n            \"Path\": \"/swagger/v1/swagger.json\"\n          }\n        }\n      ]\n    }\n  ]\n```\n\n## Version 6.0.0\n\n⚠️ Breaking change [#240](https://github.com/Burgyn/MMLib.SwaggerForOcelot/pull/240) - new way to modify swagger UI configuration.\n\n## Version 2.0.0\n\nThis version is breaking change. Because support Ocelot 16.0.0, which rename `ReRoutes` to `Routes`. See Ocelot [v16.0.0](https://github.com/ThreeMammals/Ocelot/releases/tag/16.0.0).\n\n---\nIf you have read this readme to the end, please let me know by [clicking this link](https://clicks.burgyn.online/lRUXPzJGG).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburgyn%2Fmmlib.swaggerforocelot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fburgyn%2Fmmlib.swaggerforocelot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburgyn%2Fmmlib.swaggerforocelot/lists"}