Enriched Web API Documentation using Swagger/OpenAPI in ASP.NET Core
Before selecting or attempting any integration with an API, most developers check out its API documentation. Keeping the API documentation up to date to reflect the software changes is challenging and requires time and effort. In the case of Web APIs, we would like to document the following:
- Authorization Types (e.g., API Key, Bearer token, Authorization code, etc.)
- Action Methods: The endpoints, HTTP Methods, Headers, etc.
- Data Contracts: The description of the data to be exchanged between the service and a client. We can show each parameter’s name, type, restrictions, etc.
- Examples that use the Web API to help consumers start quickly.
It would be nice to have a standardized way of describing Web APIs, to allow both humans and computers to generate, discover and understand its capabilities without requiring access to the source code. Good news, 🎉 this standard exists and is called OpenAPI Specification (OAS), based initially on the Swagger Specification.
Web API documentation provides the necessary information (e.g., endpoints, data contracts, etc.) to describe our Web API to our consumers. In addition, however, we may want to provide documentation for our source code to help developers improve and maintain it. Therefore, a
Code documentation will provide information about our projects, classes, constructors, methods, etc. To automatically generate code documentation from comments, start by reading Wagner and Warren’s (2021) article.
In this article, we will learn about
Web API documentation, how we can automatically generate it in ASP .NET Core and how to provide enriched information by offering examples, documentation per different versions, and many more 😉.
In practice, in an ASP .NET Core project, we use specific Attributes and XML comments to define all the needed information (e.g., HTTP response codes, information messages, etc.) directly to our source code. We can automatically generate a JSON or YAML document (or set of documents) that describes our API by using this information. This generated document(s) is known as
OpenAPI definition, which can be used by:
- API Documentation generation tools (e.g., Swagger UI, Redoc, etc.) to render our OpenAPI definition (e.g., as a web page).
- Code generation tools (NSwag, Swagger Codegen, etc.) to automatically generate the consumer’s source code in various programming languages.
- Testing tools to execute API requests and validate responses on the fly.
- Mock Server tools to provide a mock-fake server to return static or dynamically generated example responses.
So, by using OpenAPI in our Web API projects, we can automatically generate our documentation directly from or source code by maintaining the data annotations, XML comments and examples based on our actual data transfer classes. The two main OpenAPI implementations for .NET are Swashbuckle and NSwag. In the examples of the following sections, we will use the
Since the ASP.NET Core 5.0, the Web API templates enable the OpenAPI support by default. The template contains a NuGet dependency on Swashbuckle, register services, and add the necessary middlewares to generate a basic
OpenAPI definition file and serve it in a Web UI (via the Swagger UI tool). In the following instructions, we will see how to create a new Web API project with enabled OpenAPI support.
Open Visual Studio 2022 (you can download it from here) and select "Create a new project".
Search and select the "ASP.NET Core Web API" template and click "Next".
Name the new project (e.g. as "TutorialWebApiDocumentation"), select the location that it will be saved, and click "Next".
In the "Additional Information" dialogue, confirm that the
.NET 6.0framework is selected and the "Enable OpenAPI support" is checked. Then, click "Create".
The Web API project with OpenAPI support is ready 🎉! In .NET 6.0, there is no
Startup.csfile (Roth D., 2021). Thus, the services registration and HTTP request pipeline configuration are performed in the
launchSettings.jsonfile is configured by default to launch the Swagger's UI URL when the project starts.
Click the start debugging button (or Debug menu > Start Debugging), and our app will show the Swagger UI in a browser. In the UI, we can see the default GET
/WeatherForecastendpoint and its relative information (HTTP response code, generated example, etc.).
That’s a great start! With only a few clicks, our new API projects support OpenAPI. However, there are things that we can configure and improve to provide more information to our API consumers. For example, we could perform the actions shown in the following figure and list. However, we will see more ways to enrich our API documentation in the following sections.
- Set the appropriate response media type (e.g., application/json).
- Provide examples with real-life data (not auto-generated with dummy data).
- Include additional HTTP status codes. For example, to inform about the possible error HTTP status codes (4xx and 5xx).
Let’s assume that our current project serves API with multiple versions, and we would like to provide OpenAPI Documentation for all versions. For that purpose, we will use the project that we created in .NET Nakama (2021, December).
To provide OpenAPI Documentation, we would start by installing the Swashbuckle.AspNetCore NuGet package. To support API documentation for multiple versions, we need to install the Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer NuGet package.
Our next step is to register some services and add some middlewares. I have created some extension methods that group all the necessary actions for that purpose. You can find the source code of the extensions and examples in GitHub.
So, we can download, modify and use the following extensions in our
Program.cs (or in the
System.cs in previous .NET versions). In addition, we can see an example of the
Program.cs file here.
AddApiVersioningConfigured extension (can be found in ConfigureApiVersioning.cs) has been updated (in comparison with the one provided in article .NET Nakama (2021, December) to support versioning on our documentation.
Then, we should use the
AddSwaggerSwashbuckleConfigured extension (found in ConfigureSwaggerSwashbuckle.cs file) in our
Program.cs file to configure the Swagger generator based on our needs. In the following sections, we will see in detail several enrichment scenarios.
ConfigureSwaggerSwashbuckleOptions.cs file, we can configure the basic information (e.g., title, description, license, etc.) about our API (see Figure 3).
UseSwagger() middleware in our
Program.cs file to serve the generated OpenAPI definition(s) as JSON files and the
UseSwaggerUI() middleware to server the Swagger-UI for all discovered API versions. In the following example, we serve the API documentation only in the development environment. However, we can decide which environments to provide the documentation based on our API audience. Remember that we could only generate the JSON files and serve them (e.g., with Swagger UI) in a separate project.
Finally, if we want to see the SwaggerUI when start debugging, we will have to set the
"launchUrl": "swagger" in the
The following figure shows a Swagger UI example for an API with two versions containing essential information.
The structure of the extracted XML documentation is defined in C# by using XML documentation comments. The documentation comments support several XML tags, such as summary, return description, exceptions, list of information, etc. In this article, we will use some of them. For more information about the recommended XML tags for C#, read Wagner B., et al. (2021) article.
To enable the documentation file generation, we should set the
GenerateDocumentationFile option to True. Then, the compiler will find all comment fields with XML tags in our source code and create an XML document.
However, when this option is enabled, the compiler will generate CS1591 warnings for any public members in our project without XML documentation comments. We can exclude these warnings by including them in the
So, to enable the
GenerateDocumentationFile option and stop the CS1591 warnings we should:
- Right-click the project in
Solution Explorerand select
Edit Project File.
- Add the following PropertyGroup section (or include the options in an existing PropertyGroup).
Next, we need to include the XML documentation comments in the OpenAPI definition file. For that purpose, we should use the
IncludeXmlComments method in the
ConfigureSwaggerSwashbuckle.cs file as shown in the following code.
Finally, we should include the XML comments in our controller actions using triple slashes. For example, we can add a
summary section to describe the performed action. Figure 4 presents a part of the Swagger UI that shows the API endpoint summary.
Any consumer would need beneficial information, such as the possible HTTP status codes and their response body. In Figure 5, we can see an example where the API endpoint could return its five possible HTTP status codes (200, 400, 409, 500, and 503). To enrich the response metadata for a given action method, we should:
- Install the Swashbuckle.AspNetCore.Annotations NuGet package.
- Update the controller actions to specify the possible response codes and their response types (if any) by using the
responsetag and the
In the following code example, we set the response description of the success HTTP status code in the
response tag. In addition, we are setting all possible HTTP status codes and response types (e.g.,
IEnumerable<SampleResponse>) for the successful response.
To define the appropriate consume and produce media types, we can decorate our controller with the
[Produces] attributes. For example, if we use the
application/json, we can use the aforementioned attributes to decorate our controller, as shown in the following code example. Figure 6 shows the effect of the
[Produces] attribute in Swagger UI.
Swashbuckle.AspNetCore.Filters NuGet package provides several functionalities that significantly improve our API documentation. For example, we can create valuable request and response examples with valid data, including security requirements, custom request and response headers, etc. In addition, we can manually test our API using these features just by using the Swagger UI without modifying the auto-generated request.
To provide request and response examples with valuable and valid data, we should:
- Install the Swashbuckle.AspNetCore.Filters NuGet package.
- Enable the automatic annotation of the
ConfigureSwaggerSwashbuckle.csfile. For that purpose, we should:
- Use the
- Read the examples for the current assembly by registering the
- Use the
Then we can implement the
IExamplesProvider interface for our data transfer classes (request and response). In the following source code example, we return an example for the
SampleRequest class, shown in Figure 7.
If we use
System.ComponentModel.DataAnnotations attributes to validate our DTOs, then the validations are recognized and automatically included in the API documentation. However, we should perform the following steps if we are using FluentValidation for our DTOs.
- Install the MicroElements.Swashbuckle.FluentValidation NuGet package.
- Register the following service in the
ConfigureSwaggerSwashbuckle.csto add the fluent validation rules to the swagger generator.
To provide security information about the authorization scheme we are using (e.g., JWT Bearer), we can define it by using the following source code in the
ConfigureSwaggerSwashbuckle.cs file. In this way, the
Authorize button will be shown (Figure 10), and we can use it to specify the appropriate values (e.g., the bearer token in Figure 11).
Our API endpoints may require authorization (using the
[Authorize] attribute) or allow anonymous requests. As we can understand, it would be helpful to distinguish these cases in our Swagger UI. For that purpose, we can show the
(Auth) text next to the endpoint’s summary to quickly see which of them require authorization (Figure 12). We can perform that by using the following
OperationFilter in the
ConfigureSwaggerSwashbuckle.cs file as shown below:
Web API documentation provides the necessary information (e.g., endpoints, data contracts, etc.) to describe our Web API to our consumers. However, keeping an up to date Web API documentation is challenging and requires time and effort. Therefore, an easy and automatic process as much as possible would be a great help.
OpenAPI Specification provides a standardized way of describing Web APIs to allow both humans and computers to generate, discover and understand the API capabilities. In an ASP .NET Core project, we use specific Attributes and XML comments to define all the needed information (e.g., HTTP response codes, information messages, etc.) directly to our source code. Thus, we can provide up-to-date documentation easily as we keep our code up to date.
The essential OpenAPI tools that we would need are a) a tool to generate the OpenAPI definition and b) a tool to generate the API documentation (as a web page, PDF, etc.). This article showed how to use the Swashbuckle tools to create API documentation in an ASP.NET Core project (new or existing) with enriched information.
When creating a Web API Documentation, our goal should be to provide all the information that a consumer would need to communicate with our Web API (without having access to our code). This way, we would reduce the time to a first hello world (TTFHW) call (i.e., the time to integrate with our Web API). So let’s think about our consumers and create beautiful and valuable Web API documentation for them.
- .NET Nakama (2021, December 4). All about Web API Versioning in ASP.NET Core. https://www.dotnetnakama.com/blog/all-about-web-api-versioning-in-asp-dotnet-core/
- Roth D. (2021, August 10). ASP.NET Core updates in .NET 6 Preview 7. https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-net-6-preview-7/#minimal-host-and-template-improvements
- Wagner B. and Warren G. (2021, November 29). XML documentation comments. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/
- Wagner B., et al. (2021, November 30). Recommended XML tags for C# documentation comments. https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/xmldoc/recommended-tags