Documenting your ASP.NET Core Web API with Swashbuckle

So you’ve finished your API, it’s awesome. Does everything you expect it to do, you’ve got great unit and integration tests to cover a percentage that makes you happy and handles exceptions and resource management flawlessly.  Let’s go a step further and say that your API solves a really useful problem that would necessitate someone asking if they can consume it.  You say “No problem!  To get started you just need to read the … … “.  At that point you realize that you forgot the documentation.  Up until now (and I’ve been there) you haven’t even thought of the documentation because you have been so focused on finishing features.   What’s a developer to do?

I can’t speak for every situation but in the case of creating beautiful, Swagger standard docs when developing with ASP.NET Core there is an awesome library called Swashbuckle that can help you out.  Feel free to take a read over at Github which covers the project and the purpose but what I’ll walk you through below what you need to do and what you’ll get from an output standpoint by following along.  One aside before we begin, this won’t cover hosting your API docs but once you’ve got the JSON that this creates, any Swagger container will do.  Swaggerhub, SwaggerUI or even a WordPress plugin

Let’s Get Started

I’m a big golfer so today’s API is going to be called “Golf Bag API”.  The operations that I’m planning on support our based CRUD for Golf Balls and Clubs as they relate to your golf bag.  As with most examples, it is just enough to get you started but it is runnable and you’ll get a good feel for how things work.

When we are done, you’ll have a local endpoint the produces this

Project Setup

Fire up a new ASP.NET Web API project.  I did so using Rider but you could use Visual Studio or the CLI. Now run  dotnet add package Swashbuckle.AspNetCore to add Swashbuckle to your project.  As you can see, I’m supporting the operations with 2 controllers and a pair of DTOs to match.

I generally like to keep my controllers small and more coordinators and often have probably more than I should, but I like granularity and clear explanation.  Additionally, I never like to send my Domain Objects across the wire and often try to only send what is need.

Controller Work

Diving into into the ClubsController and let’s take a look at the [HttpGet] .   You have a few options in terms of generating your output

  • ProducesReponseType is used to determine the value status codes that the action will return.  Providing a Type will include the DTO or the payload that actually is returned when this status code is determined.  So if you if you have Error objects for specific conditions you can specify those as well.
  • XML comments on the action will generate comments on the output to be used in the documentation.

Both of these are optional, but the more you can provide for essentially free I feel the better

This action produces something that looks just like this.

Take a look at that example payload.  Isn’t that nice?!?  Notice the “Model” text next example value.  Here’s the trick, if you attribute your action correctly you get that support.  And that links down to the actual request/response which Swagger defines down at the bottom of your Docs.  Take it a step further.  If you attribute and comment your models with XML comments, DataContract and the other DataAnnotations attributes then your docs get even that much richer.  Here’s the ClubDto

And here is the representation of that in the documentation

Pretty cool isn’t it? So thinking through this as a developer against your API, they now know

  • What the URI looks like
  • What verbs you accept
  • What querystring, route and post parameters you take
  • What status codes the endpoint will return in addition to the payload
  • And definitions about the payloads themselves with strongly typed representations of what those underlying values are and the usages of those properties

And all of that by just attributing your controller actions and requests/responses.

Wiring It Up

So how does Swashbuckle know to do this?  We next need to make some modifications to our Startup.cs file.

Step 1

Inside of our ConfigureServices I’ve made these changes

What does that do?

  1. Provides configuration options
  2. Specifics the title and version for the swagger doc
  3. Tells Swashbuckle to group by GroupName (there are lots of options and the ability to override and customize this)
  4. Build in XML comments that are on the top of your props, classes and methods

Quick side note, building XML comments.  Rider in my case doesn’t have a checkbox to build this like Visual Studio does.  However, a quick edit of the csproj file will suffice.  The nowarn tells the compiler not to generate warnings based upon missing or incomplete comments.

Step 2

The second part needs a modification to the Configure method

We need to tell the ApplicationBuilder to use Swagger and then include SwaggerUI as something your API can now host (lots of ways to host Swagger but this is a nice convenience)

  1. Add the route prefix “swagger”
  2. Specify where the JSON file will live and the name

Now once you build and run you can hit http://localhost:5000/swagger and you get something that looks just like the initial picture in this post.

Wrapping Up

I’m hopeful that you able to follow along and can see how easy this was to get high quality documentation for your APIs with minimal effort.  I know on my projects currently, I just include this level of attribution and XML commenting as part of my dev flow because I know what I’m going to get on the backend.  And for those developers that will be working off your API down the line, they will be grateful.

If you are interested in the code it is located here.

I’m going to continue to try and deliver new content each week so please check back and I do appreciate you taking the time to read.


About the author

Ben Pyle is a software developer who enjoys solving problems and delighting customers with right quality software. He's a husband, father to 2 boys and avid golfer. In his free time he enjoys reading, playing lots of golf and hanging out with his family doing whatever they are into.

Leave a Reply

Your email address will not be published. Required fields are marked *