DEV Community

Paul Delcogliano
Paul Delcogliano

Posted on

Improve Your Web API with Swagger Documentation

This post is one in a series of posts I am using to further enhance my development skillset. In this post, I will describe how to improve the Mural API (my reference application used for educational purposes) using Swagger documentation. Swagger is a set of tools based upon the OpenAPI Specification (OAS) which are used for documenting Web APIs. You may be wondering why documenting your API is necessary. Well, good documentation contributes to the overall user experience and is one of the biggest factors for increased API growth and usage.

ASP.Net Core uses Swashbuckle, which is an open-source Swagger implementation used for generating API documentation. Through Swashbuckle you will generate living documentation every time you build your API, keeping the documentation in sync with the latest version of your API.

Basic Swagger Documentation

The first thing we need to do is install Swashbuckle into the API project. Swashbuckle is available as a NuGet package. I am using PowerShell to install the NuGet package.

Install-Package Swashbuckle.AspNetCore -Version 5.6.3
Enter fullscreen mode Exit fullscreen mode

Swagger functionality is injected as middleware into the ASP.Net pipeline. Open the API project's Startup.cs file and edit the ConfigureServices() method. Add the line as shown below.

services.AddSwaggerGen(c =>
{
  c.SwaggerDoc("v1", new OpenApiInfo { Title = "Mural", Version = "v1" });
});
Enter fullscreen mode Exit fullscreen mode

While still editing the Startup.cs file, locate the Configure() method and enable middleware for the Swagger UI by adding useSwagger and useSwaggerUI.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  app.UseSwagger();
  app.UseSwaggerUI(c =>
  {
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Mural V1");
  });
  /// rest of method body
Enter fullscreen mode Exit fullscreen mode

Save the Startup.cs and run the project. Swashbuckle includes an implementation of the Swagger UI, which is a Web page that provides interaction and visualization to an API's resources. Navigate to the Swagger UI page by going to localhost:44333/swagger/index.html. Note, your local port may vary. When you open this page you will see the basic documentation that comes out of the box from Swagger.
Basic Swagger Documentation

Nice! With just a few lines of code and a NuGet package, we have a documented API. But, we can enhance the documentation with additional information, like examples for calling the API methods and descriptions of the method parameters. In the next section, we'll enrich the documentation to create an even better user experience.

Providing Enhanced Documentation

We can enrich the API's documentation by including XML comments in the code. You place these comments directly before the code block about which you are commenting. The Swashbuckle tooling automatically includes XML comments in its documentation and makes them available to view via the Swagger UI Web page.

The first thing we need to do is to enable XML Comments in the project. XML comments can be enabled via several approaches. I chose to use the Project Properties Dialog as shown below.

Enable XML Comments via Project Properties Dialog

Using the dialog, navigate to the "Build" tab and click on the checkbox next to "XML Documentation file". Provide a name for the file, such as "M-url.Api.xml". Of note, when you enable XML Documentation, your code will generate warnings for any method that does not contain XML comments. If you want to disable this compiler warning, include 1591 in the Suppress warnings textbox.

Next, we need to add code to the Startup.cs file to inform Swagger where it can find the XML comments file. Replace the call to AddSwaggerGen we added earlier with the code shown below:

services.AddSwaggerGen(c =>
  {
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Mural", Version = "v1" });

    // generate the XML docs that'll drive the swagger docs
    var xmlFile = $" 
      {Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath);
  });
Enter fullscreen mode Exit fullscreen mode

Now we'll add comments to the code. We'll start identifying which content-types the API handles on requests and responses. You use the Produces and Consumes attributes on the controller class to specify the content types allowed by the API.

[Produces(MediaTypeNames.Application.Json, 
  MediaTypeNames.Application.Xml)]
[Consumes(MediaTypeNames.Application.Json, 
  MediaTypeNames.Application.Xml)]
public class SlugCollectionsController : ControllerBase
{ ... }
Enter fullscreen mode Exit fullscreen mode

In the example above, the SlugsController accepts and returns both JSON and XML. This information will appear in the Swagger documentation.

Here I've added comments to the GetSlugCollection() method:

/// <summary>
/// Returns a collection of URLs
/// </summary>
/// <param name="slugs">list of slugs to retrieve</param>
/// <remarks>
/// Sample request:
///
///     Get /api/slugscollection/(d25tRx, fN5jpz)
///
/// </remarks>
/// <returns>IEnumerable of slugs</returns>
/// <response code="200">If all requested items are 
/// found</response>
/// <response code="400">If slugs parameter is missing</response>
/// <response code="404">If number of records found doesn't equal 
/// number of records requested</response>
[HttpGet("({slugs})", Name = "GetSlugCollection")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult> GetSlugCollection([ModelBinder(BinderType = typeof(ArrayModelBinder))] IEnumerable<string> slugs)
{ ... }
Enter fullscreen mode Exit fullscreen mode

While many of the comments are self-explanatory, I do want to highlight a few of them. The following table details the interaction between each XML comment attribute and its effect on the Swagger documentation.

Comment Attribute Swagger UI Action
summary displays text next to the action method name
remarks Supplements information specified in the element. Can consist of text, JSON, or XML
response Renders as an example HTTP request in the Swagger documentation.

Looking at the code snippet above, you'll notice the additional attribute, ProducesResponseType has been added to the method. ProducesResponseType informs Swagger of the HTTP Status codes returned by the method. The response XML comment works in conjunction with the ProducesResponseType attribute to provide descriptive information for each HTTP status code the method returns.

Alternatively, in place of specifying each individual status code using ProducesResponseType, you can use the ApiConventionMethod attribute to specify 200, 400, and 404 status codes if your API produces a standard set of response codes. Here's an example:

[ApiConventionMethod(typeof(DefaultApiConventions))]
Enter fullscreen mode Exit fullscreen mode

The final version of the GetSlugCollection method's documentation is below. You can see the additional descriptions next to the parameters, the HTTP status codes being returned, and an example of calling the API using a GET HTTP method.
Enhanced Mural Documentation

There is one more change we can do to make the documentation complete. Back in the Startup.cs file, replace the call to AddSwaggerGen we modified earlier with the souped-up version shown below:

services.AddSwaggerGen(c =>
{
  c.SwaggerDoc("v1", new OpenApiInfo
  {
    Title = "Mural API",
    Description = "",
    Contact = new OpenApiContact
    {
      Name = "Paul Delcogliano",
      Email = "pdelco@gmail.com",
      Url = new Uri("https://github.com/pdelcogliano")
    },
    License = new OpenApiLicense
    {
      Name = "MIT License",
      Url = new Uri("https://opensource.org/licenses/MIT")
    }
  });

  // generate the XML docs that'll drive the swagger docs
  var xmlFile = $" 
    {Assembly.GetExecutingAssembly().GetName().Name}.xml";
  var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
  c.IncludeXmlComments(xmlPath);
});
Enter fullscreen mode Exit fullscreen mode

In this version, we are using the OpenApiInfo() method to provide additional data for the document header. We are also using the OpenApiLicense() method to provide information about the API license. Here's the final Swagger documentation, shown in all of its glory with enhanced header information, and enriched method descriptions:

Completed Mural API Documentation

Documenting an ASP.Net Core API using Swashbuckle and Swagger helps your API meet the goals of good documentation. Good documentation provides many benefits. It helps internal teams understand the API and agree on its attributes. It facilitates external clients' understanding of the API and the functionality it provides. More information about getting started with Swagger and Swashbuckle can be found here.

Top comments (0)