How to document an ASP.NET Core Web API using OpenAPI Specification (swagger)
Documenting your API is very important if you want people to be able to consume it. An API documentation should contain the list of accessible endpoints (URL, method), their parameters, and the response (http status code, body). The documentation should be readable by a human, but also by a computer. The latter is very useful to generate clients automatically.
OpenAPI Specification is the most common way to document an API:
The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.
An OpenAPI definition can then be used by documentation generation tools to display the API, code generation tools to generate servers and clients in various programming languages, testing tools, and many other use cases.
#How to add Swagger to your ASP.NET Core Web API
The idea is to generate the documentation from the code and the XML comments. So, first, you need to generate the XML documentation during the build. Then, add the package Swashbuckle.AspNetCore
and configure it.
Go in the project settings and check
XML documentation file
:Enable XML Documentation in Visual Studio
Or you can set it in the csproj file:
csproj (MSBuild project file)<PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile> </PropertyGroup>
Edit the
Startup.cs
file to register Swagger:C#public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // Configure Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "Swagger Sample", Version = "v1", // You can also set Description, Contact, License, TOS... }); // Configure Swagger to use the xml documentation file var xmlFile = Path.ChangeExtension(typeof(Startup).Assembly.Location, ".xml"); c.IncludeXmlComments(xmlFile); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Swagger Sample"); }); }
Add an API controller
C#[Route("api/[controller]")] [ApiController] public class GistController : ControllerBase { /// <summary> /// List all public gists sorted by most recently updated to least recently updated. /// </summary> /// <remarks>With pagination, you can fetch up to 3000 gists. For example, you can fetch 100 pages with 30 gists per page or 30 pages with 100 gists per page.</remarks> [HttpGet] public ActionResult<IEnumerable<Gist>> Get() { // code omitted from brevity } /// <summary> /// Get a single gist. /// </summary> /// <param name="id">The id of the gist</param> [HttpGet("{id}")] public ActionResult<Gist> Get(int id) { // code omitted from brevity } }
#Adding more information to describe your API
You can add more information to the controller actions to add more information. In XML you can set:
<summary></summary>
: Description of the action<remark></remark>
: Additional information / sample<return><return>
: Description of the return value<param name="id"></param>
: Description of an input parameter<response code="201"></response>
: Description of the return value when the status code is 201
You can also add some C# attributes such as [ProducesResponseType]
which allows specifying the model of a response for a status code.
[ProducesResponseType(201, Type = typeof(Gist))]
[ProducesResponseType(400, Type = typeof(void))]
public ActionResult Get(int id)
{
// code omitted from brevity
}
Of course, you can also add attribute and XML comment to describe your models:
public class Gist
{
/// <summary>The description of the Gist</summary>
[Required]
public string Description { get; set; }
/// <summary>Indicate whether the gist is public or private</summary>
[DefaultValue(true)]
public bool Public { get; set; }
}
If your API requires a specific header or an authentication mechanism, you can declare them in the startup.cs
file:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Title = "Swagger Sample",
Version = "v1",
});
c.AddSecurityDefinition("Bearer", new ApiKeyScheme { In = "header", Description = "Please enter JWT with Bearer into field", Name = "Authorization", Type = "apiKey" });
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{ "Bearer", Enumerable.Empty<string>() },
});
});
The Generated UI and JSON will reflect all these comments and attributes, so the consumer of your API will know exactly how they should interact with it.
#Open the Swagger UI
You can now access the generated swagger UI by navigating to http://<host>/swagger/
Swagger UI - List of endpoints
Swagger UI - List of models
Swagger UI - Details of an endpoint
You can event try your API by clicking on Try it out
.
#Conclusion
You can add documentation to your API using a standard way in a few minutes. The default UI is maybe not the most beautiful I've seen, but is very convenient. This will allow your users to use your API, or generate an SDK using swagger Codegen.
Do you have a question or a suggestion about this post? Contact me!