New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add possibility to hook into the config initialization. #2590
base: master
Are you sure you want to change the base?
Conversation
@domaindrivendev Any chance of this making it into the next version? It looks like a pretty neat/clean addition to the UI configuration to me. |
Thanks for contributing - if you'd like to continue with this pull request, please rebase against the default branch to pick up our new CI. |
672d1fd
to
a79bf7f
Compare
a79bf7f
to
0e225c0
Compare
@martincostello Rebase done 😉 |
Codecov ReportAll modified and coverable lines are covered by tests ✅
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #2590 +/- ##
=======================================
Coverage 91.66% 91.66%
=======================================
Files 91 91
Lines 3010 3010
Branches 517 517
=======================================
Hits 2759 2759
Misses 251 251
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@@ -1341,6 +1342,78 @@ app.UseSwaggerUI(c => | |||
}); | |||
``` | |||
|
|||
### Change Swagger UI Config ### | |||
|
|||
Swagger UI has a big variety of options and a mighty plugin API allowing customizations. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swagger UI has a big variety of options and a mighty plugin API allowing customizations. | |
Swagger UI has a large variety of options and a mighty plugin API allowing customizations. |
Swagger UI has a big variety of options and a mighty plugin API allowing customizations. | ||
To customize the Swagger UI (and OAuth) configuration objects before they are passed into the Swagger UI initialization, | ||
inject a custom JavaScript file which defines a global function with the following signature. | ||
In many cases this feature allows to avoid using a custom `index.html` in your project. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In many cases this feature allows to avoid using a custom `index.html` in your project. | |
In many cases this feature allows you to avoid using a custom `index.html` in your project. |
function initConfig(configObject, oauthConfigObject) { } | ||
``` | ||
|
||
Through this mechanism any options that Swagger UI supports can be set and also plugins can be registered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Through this mechanism any options that Swagger UI supports can be set and also plugins can be registered. | |
Through this mechanism any options that Swagger UI supports can be set, and also plugins can be registered. |
|
||
Through this mechanism any options that Swagger UI supports can be set and also plugins can be registered. | ||
Swagger UI is written with React so it can be a bit tricky to write custom components. | ||
Here a full example which adds a custom section to the parameters of all operations: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here a full example which adds a custom section to the parameters of all operations: | |
Here is a full example which adds a custom section to the parameters of all operations: |
// swagger-ui.js | ||
// https://swagger.io/docs/open-source-tools/swagger-ui/customization/plugin-api/ | ||
function configInit(config) { | ||
if(!config.plugins) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if(!config.plugins) { | |
if (!config.plugins) { |
return system.React.createElement('div', | ||
{ className: "parameters-wrap"}, | ||
system.React.createElement(CustomOperationDetails, props), | ||
system.React.createElement(Original, props) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example looks out-of-date compared to the example in the non-obsolete React documentation.
app.UseSwaggerUI(options = > | ||
{ | ||
options.InjectJavascript("swagger-ui.js"); | ||
}); | ||
``` | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
app.UseSwaggerUI(options = > | |
{ | |
options.InjectJavascript("swagger-ui.js"); | |
}); | |
``` | |
app.UseSwaggerUI(options => options.InjectJavascript("swagger-ui.js")); |
@@ -102,6 +102,11 @@ | |||
if (interceptors.ResponseInterceptorFunction) | |||
configObject.responseInterceptor = parseFunction(interceptors.ResponseInterceptorFunction); | |||
|
|||
// Allow adjusting config through injected JavaScript files | |||
if(typeof initConfig === "function") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if(typeof initConfig === "function") { | |
if (typeof initConfig === "function") { |
@@ -102,6 +102,11 @@ | |||
if (interceptors.ResponseInterceptorFunction) | |||
configObject.responseInterceptor = parseFunction(interceptors.ResponseInterceptorFunction); | |||
|
|||
// Allow adjusting config through injected JavaScript files | |||
if(typeof initConfig === "function") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a better way of hooking this up as a global that's more robust and/or more likely to not pollute with any existing objects (e.g. what if it was called swashbuckleInitConfig
for instance)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a sample and/or integration test that can be updated to demonstrate this somehow?
To register custom plugins and customize the Swagger UI it is currently required to provide an own
index.html
. This has the negative impact of keeping it up-to-date with Swashbuckle.This PR extends the default index.html with a new way of hooking into the Swagger UI setup allowing devs to register plugins and change settings within a custom injected JavaScript acting as entry point.
I extended also the docs to show some basics on how the Plugin API and React can be used in such a setup to customize the UI even further. We have been doing this for quite a while using a custom
index.html
but having such a feature by-default would bring benefit to everyone (and we do not need to maintain it once per API 😁).