Web API documentation using Swagger & ASP.NET Core With Visual Studio 2019


Introduction

There are more challenges we are facing for consuming a Web API because it contains  various methods such as GET,POST,PUT,DELETE. All these methods  contain various types of parameters like model,string,int,etc. Exactly we don’t know what property we need to pass in the model parameter and what are the relevant ones. These are the major challenges for a developer and so we need a proper documentation to solve this problem. That’s why we choose Swagger also known as OpenAPI and It  will provide all such benefits like interactive documentation, client SDK generation, and API discoverability. In this article we are explaining a lit bit basic configurations of Swagger in ASP.NET Core application. We can add more additional features on the Web API using swagger for that just read the reference document that we have mentioned in the Reference section.

We have tested the swagger documentation application in the latest VS 2019. So please check the following steps to kick start the initial process of installation.

1) Open Visual Studio 2019 and Click on “Create a new project”


2) Click on ASP.NET Core Web Application


3) Provision your new project and give the appropriate name and the location to be saved.


4) Choose API and Click on the Create button on the right side.


5) Open “Tools -> Nuget Package Manager -> Manage Nuget Packages for Solution…” and click on Browse tab and search “Swashbuckle.AspNetCore” in the search bar and install it.

Model

We are going to create a Employee model for the demo purpose.

namespace SwaggerDocumentation.Model
{
    public class Employee
    {

        public int id { get; set; }
		
		public string Name { get; set; }
		
		public string Adress { get; set; }

		public string Department { get; set; }

    }
}

API Version Separation

In future if we are planning to release multiple versions of API, then, for the better readability purpose we can create a version folder for the API creation. This will help us to differentiate multiple versions in the API side and Swagger documentation. In the following screenshot we have created two folders one is “v1” ( Version 1 ) and another one is “v2” ( Version 2 ). obviously v2 will contain the latest version comparing to v1.

API Controller

We have created “EmployeeController” as the API controller in our application. Here we can see at the route level api path is set as “api/v1/[controller]” because when you hit the swagger it will first check the controller level then what will happen it will take two identical controller name as “Employee”. This will create ambiguous issue in the http request controller level, for that reason we have added two different request path for both versions v1 & v2.

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using SwaggerDocumentation.Model;

namespace SwaggerDocumentation.Controllers.v1
{
    [Route("api/v1/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        // GET: api/v1/Employee
        [HttpGet]
        public List<Employee> EmployeesDetails()
        {
            List<Employee> employees = new List<Employee>
            {
               new Employee
               {
                   Name = "Rajeesh",
                   Department = "Development",
                   Adress = "Menoth Parambil"
               },

               new Employee
               {
                   Name = "Arokia",
                   Department = "R/D",
                   Adress = "Trichy Central"
               },

               new Employee
               {
                   Name = "Vijay",
                   Department = "Cloud",
                   Adress = "MP Gowliyar"
               },

            };

            return employees;
        }

        // GET: api/v1/Employee/5
        [HttpGet("{id}", Name = "Get")]
        public Employee EmployeeDetailsInformation(int id)
        {
            List<Employee> employees = new List<Employee>
            {
               new Employee
               {
                   id = 1,
                   Name = "Rajeesh",
                   Department = "Development",
                   Adress = "Menoth Parambil"
               },

               new Employee
               {
                   id = 2,
                   Name = "Arokia",
                   Department = "R/D",
                   Adress = "Trichy Central"
               },

               new Employee
               {
                   id = 3,
                   Name = "Vijay",
                   Department = "Cloud",
                   Adress = "MP Gowliyar"
               },

            };

            return employees.Find(x => x.id == id);
        }

        // POST: api/v1/Employee
        [HttpPost]
        [ApiExplorerSettings(GroupName = "v1")]
        public void Post([FromBody] string value)
        {
        }

        // PUT: api/v1/Employee/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE: api/v1/ApiWithActions/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

IControllerModelConvention

In the ASP.NET Core MVC we have application model and it will define convention abstractions that provide a simpler way to customize the behavior of the models without overriding the entire model. In simpler way we are modifying our app to follow different conventions from the default MVC behavior. The following method is clearly describing that it will take the last name of the “namespace” and it consider as the group name of the API Version. So in this case we can easily separate out versions when we  maintain multiple version of API’s in the application. The “GroupName”  can be declared as globally and locally, but in multiple API version case we can go with global scenario.

public class ApiExplorerVersionConvention : IControllerModelConvention
    {
        public void Apply(ControllerModel controller)
        {
            var controllerNamespace = controller.ControllerType.Namespace; // e.g. "Controllers.v1"
            var apiVersion = controllerNamespace.Split('.').Last().ToLower();

            controller.ApiExplorer.GroupName = apiVersion;
        }
    }

The following way we can declare group name  locally but in this scenario you need to add the following decorator for each API method .

 // POST: api/v1/Employee
        [HttpPost]
        [ApiExplorerSettings(GroupName = "v1")]
        public void Post([FromBody] string value)
        {
        }

Middleware

We need to inject swagger service in the ASP.NET Core application using the middleware in startup class. Then only we can access the entire swagger service in our application.

ConfigureServices ( Inside the Startup.cs )

ConfigureServices method gets called by the runtime so we can use this method to register the services to the container  in the application. First of all we need to add “ApiExplorerVersionConvention” convention in the MVC service like the following way.

services.AddMvc(x => x.Conventions.Add(new ApiExplorerVersionConvention()));

The following code will register the swagger in our Application. There are many properties we use in the following code like “v1” & “v2” consider as GroupName , Title is displayed as “Swagger Documentation” and “Version 1.0” & “Version 2.0” is the version separation.

// Register the Swagger generator, defining 1 or more Swagger documents
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "Swagger Documentation", Version = "Version 1.0" });
                c.SwaggerDoc("v2", new Info { Title = "Swagger Documentation", Version = "Version 2.0" });
            });

Configure ( Inside the Startup.cs )

Configure method gets called by the runtime and use this method to configure the HTTP request pipeline. We are going to enable the generated Swagger as a JSON endpoint in the middleware and it will serve to the request.

app.UseSwagger();

The swagger UI and json endpoint we can mention in the following way.

app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                c.SwaggerEndpoint("/swagger/v2/swagger.json", "My API V2");
            });

launchSettings.json

In launchSettings.json we can setup swagger as the launch URL. This is not mandatory to give because for the demo purpose we have given launch URL as swagger. Otherwise In middleware we have SwaggerEndpoint  “/swagger/v1/swagger.json” so you can enter in the browser like “http://localhost:44392/api/swagger&#8221;.

{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:62460",
      "sslPort": 44392
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "SwaggerDocumentation": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "api/values",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

 

Output

Reference

Summary

From this article we have learned the Web API documentation using Swagger & ASP.NET Core With Visual Studio 2019. I hope this article is useful for all the ASP.NET Web API beginners.

One response

  1. I’m amazed, I have to admit. Seldom do I come across a blog that’s both educative and entertaining, and let me tell you, you’ve hit the nail on the head. The issue is something too few men and women are speaking intelligently about. Now i’m very happy I came across this in my search for something relating to this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: