Skip to content

Commit 1e43cbe

Browse files
Add MapSwaggerUI and MapReDoc for endpoint routing (#3822)
Add support for using endpoint routing for SwaggerUI and ReDoc. Co-authored-by: Martin Costello <martin@martincostello.com>
1 parent fbdc3b7 commit 1e43cbe

15 files changed

Lines changed: 747 additions & 405 deletions

Swashbuckle.AspNetCore.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
<Project Path="test/WebSites/TodoApp/TodoApp.csproj" />
8181
<Project Path="test/WebSites/TopLevelSwaggerDoc/TopLevelSwaggerDoc.csproj" />
8282
<Project Path="test/WebSites/WebApi.Aot/WebApi.Aot.csproj" />
83+
<Project Path="test/WebSites/WebApi.Map/WebApi.Map.csproj" />
8384
<Project Path="test/WebSites/WebApi/WebApi.csproj" />
8485
</Folder>
8586
</Solution>
Lines changed: 169 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,169 @@
1-
# Configuration and Customization of `Swashbuckle.AspNetCore.ReDoc`
2-
3-
## Change Relative Path to the UI
4-
5-
By default, the Redoc UI will be exposed at `/api-docs`. If necessary, you can alter this when enabling the Redoc middleware:
6-
7-
<!-- markdownlint-disable MD031 MD033 -->
8-
<!-- snippet: Redoc-RoutePrefix -->
9-
<a id='snippet-Redoc-RoutePrefix'></a>
10-
```cs
11-
app.UseReDoc(options =>
12-
{
13-
options.RoutePrefix = "docs";
14-
});
15-
```
16-
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L142-L147' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-RoutePrefix' title='Start of snippet'>anchor</a></sup>
17-
<!-- endSnippet -->
18-
<!-- markdownlint-enable MD031 MD033 -->
19-
20-
## Change Document Title
21-
22-
By default, the Redoc UI will have a generic document title. You can alter this when enabling the Redoc middleware:
23-
24-
<!-- markdownlint-disable MD031 MD033 -->
25-
<!-- snippet: Redoc-DocumentTitle -->
26-
<a id='snippet-Redoc-DocumentTitle'></a>
27-
```cs
28-
app.UseReDoc(options =>
29-
{
30-
options.DocumentTitle = "My API Docs";
31-
});
32-
```
33-
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L149-L154' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-DocumentTitle' title='Start of snippet'>anchor</a></sup>
34-
<!-- endSnippet -->
35-
<!-- markdownlint-enable MD031 MD033 -->
36-
37-
## Apply Redoc Parameters
38-
39-
Redoc ships with its own set of configuration parameters, all described [in the Redoc documentation][redoc-options].
40-
In Swashbuckle.AspNetCore, most of these are surfaced through the Redoc middleware options:
41-
42-
<!-- markdownlint-disable MD031 MD033 -->
43-
<!-- snippet: Redoc-CustomOptions -->
44-
<a id='snippet-Redoc-CustomOptions'></a>
45-
```cs
46-
app.UseReDoc(options =>
47-
{
48-
options.SpecUrl("/v1/swagger.json");
49-
options.EnableUntrustedSpec();
50-
options.ScrollYOffset(10);
51-
options.HideHostname();
52-
options.HideDownloadButton();
53-
options.ExpandResponses("200,201");
54-
options.RequiredPropsFirst();
55-
options.NoAutoAuth();
56-
options.PathInMiddlePanel();
57-
options.HideLoading();
58-
options.NativeScrollbars();
59-
options.DisableSearch();
60-
options.OnlyRequiredInSamples();
61-
options.SortPropsAlphabetically();
62-
});
63-
```
64-
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L156-L174' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-CustomOptions' title='Start of snippet'>anchor</a></sup>
65-
<!-- endSnippet -->
66-
<!-- markdownlint-enable MD031 MD033 -->
67-
68-
> [!NOTE]
69-
> Using `options.SpecUrl("/v1/swagger.json")` multiple times within the same `UseReDoc(...)` will not add multiple URLs.
70-
71-
## Inject Custom CSS
72-
73-
To tweak the look and feel, you can inject additional CSS stylesheets by adding them to your `wwwroot` folder and specifying
74-
the relative paths in the middleware options:
75-
76-
<!-- markdownlint-disable MD031 MD033 -->
77-
<!-- snippet: Redoc-CustomCSS -->
78-
<a id='snippet-Redoc-CustomCSS'></a>
79-
```cs
80-
app.UseReDoc(options =>
81-
{
82-
options.InjectStylesheet("/redoc/custom.css");
83-
});
84-
```
85-
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L176-L181' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-CustomCSS' title='Start of snippet'>anchor</a></sup>
86-
<!-- endSnippet -->
87-
<!-- markdownlint-enable MD031 MD033 -->
88-
89-
It is also possible to modify the theme by using the `AdditionalItems` property. More information can be found
90-
[in the Redoc documentation][redoc-options].
91-
92-
<!-- markdownlint-disable MD031 MD033 -->
93-
<!-- snippet: Redoc-ModifyTheme -->
94-
<a id='snippet-Redoc-ModifyTheme'></a>
95-
```cs
96-
app.UseReDoc(options =>
97-
{
98-
options.ConfigObject.AdditionalItems = new Dictionary<string, object>
99-
{
100-
// Configured additional options
101-
};
102-
});
103-
```
104-
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L183-L191' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-ModifyTheme' title='Start of snippet'>anchor</a></sup>
105-
<!-- endSnippet -->
106-
<!-- markdownlint-enable MD031 MD033 -->
107-
108-
## Customize index.html
109-
110-
To customize the UI beyond the basic options listed above, you can provide your own version of the Redoc `index.html` page:
111-
112-
<!-- markdownlint-disable MD031 MD033 -->
113-
<!-- snippet: Redoc-CustomIndexHtml -->
114-
<a id='snippet-Redoc-CustomIndexHtml'></a>
115-
```cs
116-
app.UseReDoc(options =>
117-
{
118-
options.IndexStream = () => typeof(Program).Assembly
119-
.GetManifestResourceStream("CustomIndex.ReDoc.index.html"); // Requires file to be added as an embedded resource
120-
});
121-
```
122-
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L193-L199' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-CustomIndexHtml' title='Start of snippet'>anchor</a></sup>
123-
<!-- endSnippet -->
124-
<!-- markdownlint-enable MD031 MD033 -->
125-
126-
```xml
127-
<Project>
128-
<ItemGroup>
129-
<EmbeddedResource Include="CustomIndex.ReDoc.index.html" />
130-
</ItemGroup>
131-
</Project>
132-
```
133-
134-
> [!TIP]
135-
> To get started, you should base your custom `index.html` on the [default version](../src/Swashbuckle.AspNetCore.ReDoc/index.html).
136-
137-
[redoc-options]: https://github.com/Redocly/redoc/blob/main/docs/deployment/html.md#the-redoc-object
1+
# Configuration and Customization of `Swashbuckle.AspNetCore.ReDoc`
2+
3+
## Change Relative Path to the UI
4+
5+
By default, the Redoc UI will be exposed at `/api-docs`. If necessary, you can alter this when enabling the Redoc middleware:
6+
7+
<!-- markdownlint-disable MD031 MD033 -->
8+
<!-- snippet: Redoc-RoutePrefix -->
9+
<a id='snippet-Redoc-RoutePrefix'></a>
10+
```cs
11+
app.UseReDoc(options =>
12+
{
13+
options.RoutePrefix = "docs";
14+
});
15+
```
16+
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L142-L147' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-RoutePrefix' title='Start of snippet'>anchor</a></sup>
17+
<!-- endSnippet -->
18+
<!-- markdownlint-enable MD031 MD033 -->
19+
20+
## Change Document Title
21+
22+
By default, the Redoc UI will have a generic document title. You can alter this when enabling the Redoc middleware:
23+
24+
<!-- markdownlint-disable MD031 MD033 -->
25+
<!-- snippet: Redoc-DocumentTitle -->
26+
<a id='snippet-Redoc-DocumentTitle'></a>
27+
```cs
28+
app.UseReDoc(options =>
29+
{
30+
options.DocumentTitle = "My API Docs";
31+
});
32+
```
33+
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L149-L154' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-DocumentTitle' title='Start of snippet'>anchor</a></sup>
34+
<!-- endSnippet -->
35+
<!-- markdownlint-enable MD031 MD033 -->
36+
37+
## Apply Redoc Parameters
38+
39+
Redoc ships with its own set of configuration parameters, all described [in the Redoc documentation][redoc-options].
40+
In Swashbuckle.AspNetCore, most of these are surfaced through the Redoc middleware options:
41+
42+
<!-- markdownlint-disable MD031 MD033 -->
43+
<!-- snippet: Redoc-CustomOptions -->
44+
<a id='snippet-Redoc-CustomOptions'></a>
45+
```cs
46+
app.UseReDoc(options =>
47+
{
48+
options.SpecUrl("/v1/swagger.json");
49+
options.EnableUntrustedSpec();
50+
options.ScrollYOffset(10);
51+
options.HideHostname();
52+
options.HideDownloadButton();
53+
options.ExpandResponses("200,201");
54+
options.RequiredPropsFirst();
55+
options.NoAutoAuth();
56+
options.PathInMiddlePanel();
57+
options.HideLoading();
58+
options.NativeScrollbars();
59+
options.DisableSearch();
60+
options.OnlyRequiredInSamples();
61+
options.SortPropsAlphabetically();
62+
});
63+
```
64+
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L156-L174' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-CustomOptions' title='Start of snippet'>anchor</a></sup>
65+
<!-- endSnippet -->
66+
<!-- markdownlint-enable MD031 MD033 -->
67+
68+
> [!NOTE]
69+
> Using `options.SpecUrl("/v1/swagger.json")` multiple times within the same `UseReDoc(...)` will not add multiple URLs.
70+
71+
## Inject Custom CSS
72+
73+
To tweak the look and feel, you can inject additional CSS stylesheets by adding them to your `wwwroot` folder and specifying
74+
the relative paths in the middleware options:
75+
76+
<!-- markdownlint-disable MD031 MD033 -->
77+
<!-- snippet: Redoc-CustomCSS -->
78+
<a id='snippet-Redoc-CustomCSS'></a>
79+
```cs
80+
app.UseReDoc(options =>
81+
{
82+
options.InjectStylesheet("/redoc/custom.css");
83+
});
84+
```
85+
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L176-L181' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-CustomCSS' title='Start of snippet'>anchor</a></sup>
86+
<!-- endSnippet -->
87+
<!-- markdownlint-enable MD031 MD033 -->
88+
89+
It is also possible to modify the theme by using the `AdditionalItems` property. More information can be found
90+
[in the Redoc documentation][redoc-options].
91+
92+
<!-- markdownlint-disable MD031 MD033 -->
93+
<!-- snippet: Redoc-ModifyTheme -->
94+
<a id='snippet-Redoc-ModifyTheme'></a>
95+
```cs
96+
app.UseReDoc(options =>
97+
{
98+
options.ConfigObject.AdditionalItems = new Dictionary<string, object>
99+
{
100+
// Configured additional options
101+
};
102+
});
103+
```
104+
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L183-L191' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-ModifyTheme' title='Start of snippet'>anchor</a></sup>
105+
<!-- endSnippet -->
106+
<!-- markdownlint-enable MD031 MD033 -->
107+
108+
## Customize index.html
109+
110+
To customize the UI beyond the basic options listed above, you can provide your own version of the Redoc `index.html` page:
111+
112+
<!-- markdownlint-disable MD031 MD033 -->
113+
<!-- snippet: Redoc-CustomIndexHtml -->
114+
<a id='snippet-Redoc-CustomIndexHtml'></a>
115+
```cs
116+
app.UseReDoc(options =>
117+
{
118+
options.IndexStream = () => typeof(Program).Assembly
119+
.GetManifestResourceStream("CustomIndex.ReDoc.index.html"); // Requires file to be added as an embedded resource
120+
});
121+
```
122+
<sup><a href='/test/WebSites/DocumentationSnippets/WebApplicationExtensions.cs#L193-L199' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-CustomIndexHtml' title='Start of snippet'>anchor</a></sup>
123+
<!-- endSnippet -->
124+
<!-- markdownlint-enable MD031 MD033 -->
125+
126+
```xml
127+
<Project>
128+
<ItemGroup>
129+
<EmbeddedResource Include="CustomIndex.ReDoc.index.html" />
130+
</ItemGroup>
131+
</Project>
132+
```
133+
134+
> [!TIP]
135+
> To get started, you should base your custom `index.html` on the [default version](../src/Swashbuckle.AspNetCore.ReDoc/index.html).
136+
137+
[redoc-options]: https://github.com/Redocly/redoc/blob/main/docs/deployment/html.md#the-redoc-object
138+
139+
## Use `MapReDoc` with endpoint routing
140+
141+
`MapReDoc` is an endpoint-routing alternative to `UseReDoc`. The options API is the same, so all customization examples on this page also apply when using `MapReDoc`.
142+
143+
<!-- markdownlint-disable MD031 MD033 -->
144+
<!-- snippet: Redoc-MapReDoc -->
145+
<a id='snippet-Redoc-MapReDoc'></a>
146+
```cs
147+
app.MapReDoc();
148+
```
149+
<sup><a href='/test/WebSites/WebApi.Map/Program.cs#L33-L35' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-MapReDoc' title='Start of snippet'>anchor</a></sup>
150+
<!-- endSnippet -->
151+
<!-- markdownlint-enable MD031 MD033 -->
152+
153+
The main differences are:
154+
155+
- **Use**ReDoc adds middleware directly to the request pipeline and returns `IApplicationBuilder`.
156+
- **Map**ReDoc maps ReDoc via endpoint routing and returns `IEndpointConventionBuilder`.
157+
158+
- Because `MapReDoc` returns an endpoint convention builder, you can attach endpoint metadata/conventions (for example, authorization policies) directly to the mapped ReDoc endpoint.
159+
160+
<!-- markdownlint-disable MD031 MD033 -->
161+
<!-- snippet: Redoc-MapReDoc-RequireAuthorization -->
162+
<a id='snippet-Redoc-MapReDoc-RequireAuthorization'></a>
163+
```cs
164+
app.MapReDoc("redoc-auth")
165+
.RequireAuthorization(); // Remember to also add RequireAuthorization to MapSwagger
166+
```
167+
<sup><a href='/test/WebSites/WebApi.Map/Program.cs#L37-L40' title='Snippet source file'>snippet source</a> | <a href='#snippet-Redoc-MapReDoc-RequireAuthorization' title='Start of snippet'>anchor</a></sup>
168+
<!-- endSnippet -->
169+
<!-- markdownlint-enable MD031 MD033 -->

0 commit comments

Comments
 (0)