Skip to content

Commit 8c20451

Browse files
Add build-time OpenAPI generation doc (#33359)
* Add build-time OpenAPI generation docs * Fix references to sample app * Apply suggestions from code review Co-authored-by: Tom Dykstra <[email protected]> * Fix snippet paths in files --------- Co-authored-by: Tom Dykstra <[email protected]>
1 parent 67960a2 commit 8c20451

File tree

16 files changed

+164
-21
lines changed

16 files changed

+164
-21
lines changed

aspnetcore/fundamentals/openapi/aspnetcore-openapi.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ The following code:
6767
* Adds OpenAPI services.
6868
* Enables the endpoint for viewing the OpenAPI document in JSON format.
6969

70-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_first&highlight=3,7)]
70+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_first&highlight=3,7)]
7171

7272
Launch the app and navigate to `https://localhost:<port>/openapi/v1.json` to view the generated OpenAPI document.
7373

@@ -649,13 +649,13 @@ Because the OpenAPI document is served via a route handler endpoint, any customi
649649
650650
The OpenAPI endpoint doesn't enable any authorization checks by default. However, authorization checks can be applied to the OpenAPI document. In the following code, access to the OpenAPI document is limited to those with the `tester` role:
651651
652-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_mapopenapiwithauth)]
652+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_mapopenapiwithauth)]
653653
654654
#### Cache generated OpenAPI document
655655
656656
The OpenAPI document is regenerated every time a request to the OpenAPI endpoint is sent. Regeneration enables transformers to incorporate dynamic application state into their operation. For example, regenerating a request with details of the HTTP context. When applicable, the OpenAPI document can be cached to avoid executing the document generation pipeline on each HTTP request.
657657
658-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_mapopenapiwithcaching)]
658+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_mapopenapiwithcaching)]
659659
660660
<a name="transformers"></a>
661661
@@ -689,13 +689,13 @@ Transformers can be registered onto the document by calling the <xref:Microsoft.
689689
* Register a schema transformer using an instance of <xref:Microsoft.AspNetCore.OpenApi.IOpenApiSchemaTransformer>.
690690
* Register a schema transformer using a DI-activated <xref:Microsoft.AspNetCore.OpenApi.IOpenApiSchemaTransformer>.
691691
692-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_transUse&highlight=8-19)]
692+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_transUse&highlight=8-19)]
693693
694694
### Execution order for transformers
695695
696696
Transformers execute in first-in first-out order based on registration. In the following snippet, the document transformer has access to the modifications made by the operation transformer:
697697
698-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_transInOut&highlight=3-9)]
698+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_transInOut&highlight=3-9)]
699699
700700
### Use document transformers
701701
@@ -707,18 +707,18 @@ Document transformers have access to a context object that includes:
707707
708708
Document transformers can also mutate the OpenAPI document that is generated. The following example demonstrates a document transformer that adds some information about the API to the OpenAPI document.
709709
710-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_documenttransformer1)]
710+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_documenttransformer1)]
711711
712712
Service-activated document transformers can utilize instances from DI to modify the app. The following sample demonstrates a document transformer that uses the <xref:Microsoft.AspNetCore.Authentication.IAuthenticationSchemeProvider> service from the authentication layer. It checks if any JWT bearer-related schemes are registered in the app and adds them to the OpenAPI document's top level:
713713
714-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_documenttransformer2)]
714+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_documenttransformer2)]
715715
716716
Document transformers are unique to the document instance they're associated with. In the following example, a transformer:
717717
718718
* Registers authentication-related requirements to the `internal` document.
719719
* Leaves the `public` document unmodified.
720720
721-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_multidoc_operationtransformer1)]
721+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_multidoc_operationtransformer1)]
722722
723723
### Use operation transformers
724724
@@ -735,7 +735,7 @@ Operation transformers have access to a context object which contains:
735735
736736
For example, the following operation transformer adds `500` as a response status code supported by all operations in the document.
737737
738-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_operationtransformer1)]
738+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_operationtransformer1)]
739739
740740
### Use schema transformers
741741
@@ -752,7 +752,7 @@ Schema transformers have access to a context object which contains:
752752
753753
For example, the following schema transformer sets the `format` of decimal types to `decimal` instead of `double`:
754754
755-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_schematransformer1)]
755+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_schematransformer1)]
756756
757757
## Additional resources
758758
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
title: Generate OpenAPI documents at build time
3+
author: captainsafia
4+
description: Learn how to generate OpenAPI documents in your application's build step
5+
ms.author: safia
6+
monikerRange: '>= aspnetcore-6.0'
7+
ms.custom: mvc
8+
ms.date: 8/13/2024
9+
uid: fundamentals/openapi/buildtime-openapi
10+
---
11+
12+
# Generate OpenAPI documents at build-time
13+
14+
In typical web applications, OpenAPI documents are generated at run-time and served via an HTTP request to the application server.
15+
16+
In some scenarios, it's helpful to generate the OpenAPI document during the application's build step. These scenarios include:
17+
18+
- Generating OpenAPI documentation that is committed into source control.
19+
- Generating OpenAPI documentation that is used for spec-based integration testing.
20+
- Generating OpenAPI documentation that is served statically from the web server.
21+
22+
To add support for generating OpenAPI documents at build time, install the `Microsoft.Extensions.ApiDescription.Server` package:
23+
24+
### [Visual Studio](#tab/visual-studio)
25+
26+
Run the following command from the **Package Manager Console**:
27+
28+
```powershell
29+
Install-Package Microsoft.Extensions.ApiDescription.Server -IncludePrerelease
30+
```
31+
32+
### [.NET CLI](#tab/net-cli)
33+
34+
Run the following command in the directory that contains the project file:
35+
36+
```dotnetcli
37+
dotnet add package Microsoft.Extensions.ApiDescription.Server --prerelease
38+
```
39+
---
40+
41+
Upon installation, this package will automatically generate the Open API document(s) associated with the application during build and populate them into the application's output directory.
42+
43+
```cli
44+
$ dotnet build
45+
$ cat bin/Debug/net9.0/{ProjectName}.json
46+
```
47+
48+
## Customizing build-time document generation
49+
50+
### Modifying the output directory of the generated Open API file
51+
52+
By default, the generated OpenAPI document will be emitted to the application's output directory. To modify the location of the emitted file, set the target path in the `OpenApiDocumentsDirectory` property.
53+
54+
```xml
55+
<PropertyGroup>
56+
<OpenApiDocumentsDirectory>./</OpenApiDocumentsDirectory>
57+
</PropertyGroup>
58+
```
59+
60+
The value of `OpenApiDocumentsDirectory` is resolved relative to the project file. Using the `./` value above will emit the OpenAPI document in the same directory as the project file.
61+
62+
### Modifying the output file name
63+
64+
By default, the generated OpenAPI document will have the same name as the application's project file. To modify the name of the emitted file, set the `--file-name` argument in the `OpenApiGenerateDocumentsOptions` property.
65+
66+
```xml
67+
<PropertyGroup>
68+
<OpenApiGenerateDocumentsOptions>--file-name my-open-api</OpenApiGenerateDocumentsOptions>
69+
</PropertyGroup>
70+
```
71+
72+
### Selecting the OpenAPI document to generate
73+
74+
Some applications may be configured to emit multiple OpenAPI documents, for various versions of an API or to distinguish between public and internal APIs. By default, the build-time document generator will emit files for all documents that are configured in an application. To only emit for a single document name, set the `--document-name` argument in the `OpenApiGenerateDocumentsOptions` property.
75+
76+
```xml
77+
<PropertyGroup>
78+
<OpenApiGenerateDocumentsOptions>--document-name v2</OpenApiGenerateDocumentsOptions>
79+
</PropertyGroup>
80+
```
81+
82+
## Customizing run-time behavior during build-time document generation
83+
84+
Under the hood, build-time OpenAPI document generation functions by launching the application's entrypoint with an inert server implementation. This is a requirement to produce accurate OpenAPI documents since all information in the OpenAPI document cannot be statically analyzed. Because the application's entrypoint is invoked, any logic in the applications' startup will be invoked. This includes code that injects services into the DI container or reads from configuration. In some scenarios, it's necessary to restrict the codepaths that will run when the application's entry point is being invoked from build-time document generation. These scenarios include:
85+
86+
- Not reading from certain configuration strings.
87+
- Not registering database-related services.
88+
89+
In order to restrict these codepaths from being invoked by the build-time generation pipeline, they can be conditioned behind a check of the entry assembly like so:
90+
91+
```csharp
92+
using System.Reflection;
93+
94+
var builder = WebApplication.CreateBuilder();
95+
96+
if (Assembly.GetEntryAssembly()?.GetName().Name != "GetDocument.Insider")
97+
{
98+
builder.Services.AddDefaults();
99+
}
100+
```

aspnetcore/fundamentals/openapi/overview.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ ASP.NET Core apps provide built-in support for generating information about endp
2727

2828
The following code is generated by the ASP.NET Core minimal web API template and uses OpenAPI:
2929

30-
[!code-csharp[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/Program.cs?name=snippet_default&highlight=5,9-12)]
30+
[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_default&highlight=5,9-12)]
3131

3232
In the preceding highlighted code:
3333

@@ -45,7 +45,7 @@ The [`Microsoft.AspNetCore.OpenApi`](https://www.nuget.org/packages/Microsoft.As
4545

4646
To use the `Microsoft.AspNetCore.OpenApi` package, add it as a PackageReference to a project file:
4747

48-
[!code-xml[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/projectFile.xml?highlight=15)]
48+
[!code-xml[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/projectFile.xml?highlight=15)]
4949

5050
To learn more about the `Microsoft.AspNetCore.OpenApi` package, see <xref:fundamentals/openapi/aspnetcore-openapi>.
5151

@@ -58,7 +58,7 @@ Document generation at build time is enabled by setting the `OpenApiGenerateDocu
5858
By default, the generated OpenAPI document is saved to the `obj` directory, but you can customize
5959
the output directory by setting the `OpenApiDocumentsDirectory` property.
6060

61-
[!code-xml[](~/fundamentals/minimal-apis/9.0-samples/WebMinOpenApi/projectFile.xml?highlight=9-12,16-19)]
61+
[!code-xml[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/projectFile.xml?highlight=9-12,16-19)]
6262

6363
## ASP.NET Core OpenAPI source code on GitHub
6464

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<TargetFramework>net9.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
7+
<OpenApiDocumentsDirectory>./</OpenApiDocumentsDirectory>
8+
<OpenApiGenerateDocumentsOptions>--file-name my-open-api</OpenApiGenerateDocumentsOptions>
79
</PropertyGroup>
810

911
<PropertyGroup>
@@ -19,7 +21,7 @@
1921
<PrivateAssets>all</PrivateAssets>
2022
</PackageReference>
2123
<PackageReference Include="Scalar.AspNetCore" Version="1.0.1" />
22-
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="6.5.0" />
24+
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUi" Version="6.7.0" />
2325
</ItemGroup>
2426

2527
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"sdk": {
3+
"version": "9.0.100-rc.1.24414.13"
4+
}
5+
}

0 commit comments

Comments
 (0)