Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Danielku15
Copy link

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 😁).

@esbenbach
Copy link
Contributor

@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.

Havunen added a commit to Havunen/DotSwashbuckle2 that referenced this pull request Feb 12, 2024
Havunen added a commit to Havunen/DotSwashbuckle that referenced this pull request Feb 18, 2024
@martincostello
Copy link
Collaborator

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.

@Danielku15
Copy link
Author

@martincostello Rebase done 😉

@codecov-commenter
Copy link

codecov-commenter commented Apr 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.66%. Comparing base (9e77996) to head (0e225c0).

❗ 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           
Flag Coverage Δ
Linux 91.66% <ø> (ø)
Windows 91.66% <ø> (ø)
macOS 91.66% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@@ -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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!config.plugins) {
if (!config.plugins) {

Comment on lines +1398 to +1402
return system.React.createElement('div',
{ className: "parameters-wrap"},
system.React.createElement(CustomOperationDetails, props),
system.React.createElement(Original, props)
);
Copy link
Collaborator

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.

Comment on lines +1410 to +1416
app.UseSwaggerUI(options = >
{
options.InjectJavascript("swagger-ui.js");
});
```


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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") {
Copy link
Collaborator

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)?

Copy link
Collaborator

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants