In the .NET ecosystem, Swagger is a common way to define and document our APIs. In this article, we will look at how to show query parameters in Swagger.
Let’s make a start.
Swagger And Query Parameters
Swagger is a framework for designing, documenting, and consuming RESTful Web APIs. It provides us with tools to describe the structure and behavior of our APIs, which leads to easier development, documentation, testing, and sharing.
Now to query parameters, we need to note that, they are optional key-value pairs included in the request URL. They are added to the right of the question mark sign (?)
. We mostly use them in the GET
routes to pass additional filter information. To learn more about it, check out how to pass parameters with a GET request in ASP.NET Core.
Let’s get right into setting up our project!
Add Query Parameters to Swagger
To start, let’s create an ASP.NET Core Web API project. We can create a project by using the ASP.NET Core Web API template in Visual Studio, or by using the .NET CLI:
dotnet new webapi
We are going to use the default GET()
method inside the WeatherForecastController
class:
[HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); }
Here, the endpoint GetWeatherForecast()
randomly creates and returns five WeatherForecast
objects. We can also notice that the method doesn’t accept any parameters.
Let’s run our project to have a look at the Swagger UI, which is added to our project by default:
Our GetWeatherForecast()
endpoint is the only endpoint that is shown on the Swagger UI, and because it does not accept any parameters, we see no parameters displaying.
Let’s add some query parameters to the GetWeatherForecast()
route, so we can delve into describing and displaying them on the Swagger UI.
Suppose we want to specify how much weather data our route should return:
[HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get([FromQuery] int limit) { return Enumerable.Range(1, limit).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); }
We include an integer parameter limit
, which we decorate with the [FromQuery]
attribute. Then, we use the limit
argument we receive from the request to replace the hardcoded number when specifying the range of the WeatherForecast
data that is created.
Let’s run our application again to see our query parameter:
The parameter limit
we added is visible, and in addition to the parameter name, we see the parameter’s type integer and its inclusion in the query. But the description property is empty.
On this note, let’s now add a description to the query parameter, and display it in the Swagger definition.
Query Parameters Description
To add query parameter descriptions, we will use XML comments, which is a common way to document the code directly in the source files.
To add XML comments to the object we want to document, we type ///
above it and press enter. This generates the default template explaining the object, which we can modify. In our case, we want to comment on the GetWeatherForecast()
method of the WeatherForecastController
class:
/// <summary> /// /// </summary> /// <param name="limit"></param> /// <returns></returns> [HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get([FromQuery] int limit) { return Enumerable.Range(1, limit).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); }
In the default XML comments template, we have a couple of tags. First, there is a tag for method summary
, then, a tag to define and describe parameters param
, and lastly a returns
tag.
For us to describe the query parameter limit
, let’s add a description in between the <param>
tags:
/// <param name="limit">Number of the weather forecast data we want to return in the response</param>
Let’s note that, we only have one parameter, but if we had more, each parameter would get its param
tag and a name
attribute that corresponds to its name.
Now, let’s run our application:
Our Swagger UI still looks the same. It doesn’t show the description we just added to the limit
parameter. This is because Swagger doesn’t include XML comments by default.
For the comments to show, we still have some extra setup to complete. Let’s start working on them.
Adding XML Comments
First, let’s configure our project file to generate an XML documentation file:
<PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup>
Inside the PropertyGroup
tag, we add the <GenerateDocumentationFile>true</GenerateDocumentationFile>
. This line tells the .NET compiler to generate the XML documentation file from the XML comments found within the source code.
Let’s build our solution, to make our documentation file available.
Next, let’s configure Swagger to use this XML file in the Program
class:
builder.Services.AddSwaggerGen(c => { var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); });
Initially, we obtain the name of the XML documentation file from the name of the executing assembly and assign it to the xmlFile
variable.
Then, we combine the file name and the application’s base directory in the xmlPath
variable to obtain the full path. Finally, we tell Swagger to include the XML comments from the xmlPath
variable in our generated API documentation by using the IncludeXmlComments()
method.
With this set, now let’s run our application:
Great! The Swagger UI now displays our query parameter with its description.
We are almost done, but before we conclude, let’s see how to add a description to query parameters defined as part of an object.
Query Parameters Object Description
An alternative method to direct parameter specification in a route which we discussed earlier, is to create a distinct object to encapsulate all query parameters:
/// <summary> /// /// </summary> /// <param name="parameters"></param> /// <returns></returns> [HttpGet(Name = "GetWeatherForecast")] public IEnumerable<WeatherForecast> Get([FromQuery] Parameters parameters) { return Enumerable.Range(1, parameters.Limit).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } public record Parameters { public int Limit { get; set; } }
Here, we create a new record Parameters
with the property Limit
, and accept it as an argument in the GetWeatherForecast()
route. Additionally, we regenerate the XML comments for the GetWeatherForecast()
method.
Now, let’s describe the Limit
property:
public record Parameters { /// <summary> /// Number of the weather forecast data we want to return in the response /// </summary> public int Limit { get; set; } }
Since the Limit
is a property of a record, in this instance, we explain it in the summary
tag.
Finally, let’s run our application:
It’s good to note that, in cases where the record object contains multiple properties we need to write the summary description for each property we want to describe.
Conclusion
In this article, we have looked at how to add query parameter descriptions and show them in the Swagger UI. We initially discussed how to accomplish this using a query parameter in the route. Additionally, we also looked at how to describe query parameters contained in an object.