ASP.NET - Streamlining OpenAPI Documentation

Daniel Opitz
Daniel Opitz
20 Mar 2024

A Web-Centric Approach

The ASP.NET Core team moves away from Swashbuckle creates room for creativity as the framework develops, especially in how it handles API documentation and integrates OpenAPI (previously Swagger). Since Microsoft.AspNetCore.OpenApi will be improved in.NET 9 with a focus toward document generation, other approaches have a chance to adopt and expand OpenAPI support. In the middle of this shift, I offer a different approach for integrating Swagger OpenAPI that makes use of the web’s simplicity and universality: Supplying an HTML file (Swagger-UI) and a YAML file that are rendered in the browser to show the OpenAPI specification.

Swagger-UI

Swagger UI is a collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a OpenAPI specification (Yaml file) without requiring the implementation of its server logic.

Swagger UI

Using HTML and YAML for OpenAPI Documentation

This methodology is centered around the creation and distribution of two core elements:

Swagger-UI HTML Page: A static HTML page that uses Swagger-UI, an interactive API documentation web tool that renders OpenAPI specifications into a user-friendly and interactive interface.

OpenAPI Specification YAML File: The API’s OpenAPI specification, defined in YAML format, serves as the source of truth for the API documentation.

Benefits of the HTML/YAML Approach

Besides the accessibility, there are even more benefits such as:

Enhanced Change Management: By relying on static assets like HTML and YAML, this approach minimizes the complexity involved in API documentation, making it easier to maintain and update.

The process of documenting your API and making updates to its specification is now handled directly within the YAML file for each version of your API. This means that the OpenAPI schema for your API (including descriptions of endpoints, parameters, and responses) will be manually written and updated in the YAML file, rather than being automatically generated from the source code.

This approach allows for greater flexibility and control over the API documentation, but it requires that changes to the API are carefully reflected in the YAML file to ensure accuracy and consistency of the documentation.

It’s essential to keep the documentation up to date with any modifications or additions to the API to provide users with a reliable and comprehensive understanding of the API’s capabilities.

Additionally, by incorporating the OpenAPI YAML file into your version control system, you can precisely track and manage changes over time. This setup enhances collaboration and change management, allowing for a clear history of modifications and facilitating easier rollback if needed.

To modify a YAML file, you can use a variety of tools ranging from Swagger Editor to more sophisticated editors like Visual Studio Code.

Flexibility: Developers can easily customize the Swagger-UI page to fit their branding or add additional functionality, offering a tailor-made documentation experience.

Portability: The YAML file can be distributed independently of the application, allowing for easy sharing, version control, and use in other tools or environments.

By managing your API documentation through YAML files and a static Swagger UI, you have the flexibility to host your documentation on any server or platform that supports static content.

This approach is not limited to your ASP.NET Core application’s server; you can easily deploy the same set of documentation files (index.html and the YAML OpenAPI schema) on external servers, cloud storage services, or even on GitHub Pages.

💡 Note: I know, this method does not aligns with the direction of ASP.NET Core team, but it offers a practical and efficient solution to the challenges of API documentation in the evolving landscape of web development.

Setup

To set up a directory structure for hosting Swagger UI and your OpenAPI schema in an ASP.NET Core project, follow these instructions.

Create the wwwroot Folder

If your ASP.NET Core project does not already have a wwwroot folder at its root, create one. This folder is the web root directory and serves as the base path for your web application’s static files.

Add a docs/v1 Subfolder

Inside the wwwroot folder, create a new folder path docs/v1. This path will host the Swagger UI and your OpenAPI schema for version 1 of your API.

Add index.html for Swagger UI

Inside the docs/v1 folder, create a file named index.html. This HTML file will include the Swagger UI setup.

Copy / paste the following source-code into the index.html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>API Specification - Swagger UI</title>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.12.0/swagger-ui.min.css">
</head>
<body>
    <div id="swagger-ui"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.12.0/swagger-ui-bundle.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.12.0/swagger-ui-standalone-preset.min.js"></script>
    <script>
        window.onload = async function () {
            try {
                const response = await fetch('openapi.yml');
                if (!response.ok) {
                    throw new Error('Network response was not ok.');
                }
                const yaml = await response.text();
                const ui = SwaggerUIBundle({
                    spec: jsyaml.load(yaml.trim()),
                    dom_id: '#swagger-ui',
                    deepLinking: true,
                    supportedSubmitMethods: [],
                    presets: [
                        SwaggerUIBundle.presets.apis,
                    ],
                    plugins: [
                        SwaggerUIBundle.plugins.DownloadUrl
                    ],
                });
                window.ui = ui;
            } catch (error) {
                alert("Error loading YAML file: " + error.message);
            }
        }
    </script>
</body>
</html>

This HTML file serves to display an API specification using Swagger UI, a tool that renders OpenAPI specifications into interactive API documentation.

Upon loading, the file fetches an API schema from a openapi.yml file using a HTTPS network request, processes the YAML content to JSON using the js-yaml library, and then initializes the Swagger UI with this processed specification.

The HTML includes links to CSS for styling and JavaScript libraries for Swagger UI functionality and YAML processing.

Add Your OpenAPI Schema YAML File

Within the docs/v1 directory, create your OpenAPI schema file with a .yml extension (e.g., openapi.yml). This YAML file contains your API’s specification in the OpenAPI format.

Copy the following sample API specification or use your own file:

openapi: 3.0.0
info:
  title: Sample API
  description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
  version: 0.1.9

servers:
  - url: http://api.example.com/v1
    description: Optional server description, e.g. Main (production) server
  - url: http://staging-api.example.com
    description: Optional server description, e.g. Internal staging server for testing

paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in CommonMark or HTML.
      responses:
        '200':    # status code
          description: A JSON array of user names
          content:
            application/json:
              schema: 
                type: array
                items: 
                  type: string

Example project:

project

To serve the static files you’ve placed in the wwwroot folder and its subdirectories, you’ll need to enable the static files middleware in your ASP.NET Core application. This is done by adding app.UseStaticFiles(); to the Configure method in your Startup.cs or Program.cs file.

// ...

app.UseDefaultFiles();
app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true
});

// app.MapControllers();

app.UseRouting();

// ...

Notice: The StaticFiles middleware should be added before the Routing or Controllers middleware.

With the setup complete, you can access your Swagger UI by navigating to https://<your-host>/docs/v1/index.html or just https://<your-host>/docs/v1/ in a web browser. This will render your API documentation using Swagger UI, allowing you to interact with your API’s endpoints directly.

Preview

swagger

New API Versions

With this YAML-based documentation approach for your Swagger UI, it becomes possible to adopt a “design-first” methodology for your APIs. This means you can design and prototype new APIs or endpoints without writing any actual code (such as actions or controllers) upfront. You can outline the entire API structure, define endpoints, parameters, and responses directly within the YAML file. This enables you to present a comprehensive proposal of the new API version or changes to stakeholders or customers for discussion and approval before any development starts.

When introducing a new version (e.g., v2) of your API, follow these steps to ensure your Swagger UI documentation reflects the updated version:

Conclusion

This setup organizes your API documentation neatly within your ASP.NET Core project, making it easily accessible while keeping it separate from your application logic and safe from the next breaking-changes in the .NET ecosystem.