• Blog
  • Integration of Swagger with .NET Core Product Catalog API

Integration of Swagger with .NET Core Product Catalog API

Practical tips for your project

Publish date:
Discover more of what matters to you

Overview

In this article, we will talk about the way to integrate Swagger into the API of the product catalog. This can be a great method to generate interactive API documentation that can be easily shared with developers.

Application Overview

We have a .NET Core 8 API application with endpoints for an e-commerce product catalog. It includes operations like listing, creating, updating, and deleting products in the inventory. A front-end client can interact with this API to display and manage product information effectively.

The core entity of this system is the Product class with a unique identity, various attributes, and its stock quantity.

123456789101112
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
}

For data persistence and simplicity, Entity Framework (EF Core 8) is the ORM (Object Relational Mapper) and an in-memory database. The setup process involves: 

  • The installation of the EF Core in-memory database provider:
1
dotnet add package Microsoft.EntityFrameworkCore.InMemory –version 8.0.8
  • The definition of the context class:
123456
public class ProductCatalogContext : DbContext
{
public DbSet<Product> Products { get; set; }
public ProductCatalogContext(DbContextOptions<ProductCatalogContext> options) : base(options) { }
}
  • The DbContext service registration:
1234
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ProductCatalogContext>(options =>
options.UseInMemoryDatabase("ProductCatalog"));

We have chosen a simple in-memory database to keep the focus on the Swagger integration. Although an in-memory database is primarily used for testing, it will be easy to switch to another database like SQLite or SQL Server.

To interact with the database, we have a Repository class with some methods acting upon the corresponding data using the Product Catalog DbContext:

1234567891011121314151617181920212223242526272829303132333435363738394041
public class ProductRepository : IProductRepository
{
private readonly ProductCatalogContext _context;
public ProductRepository(ProductCatalogContext context)
{
_context = context;
}
public async Task<IReadOnlyList<Product>> GetAllProductsAsync()
{
return await _context.Products.ToListAsync();
}
public async Task<Product> GetProductByIdAsync(Guid id)
{
return await _context.Products.FindAsync(id);
}
public async Task AddProductAsync(Product product)
{
_context.Products.Add(product);
await _context.SaveChangesAsync();
}
public async Task UpdateProductAsync(Product product)
{
_context.Entry(product).State = EntityState.Modified;
await _context.SaveChangesAsync();
}
public async Task DeleteProductAsync(Guid id)
{
var product = await _context.Products.FindAsync(id);
if (product != null)
{
_context.Products.Remove(product);
await _context.SaveChangesAsync();
}
}
}

In Program.cs, we can register the IProductRepository interface with its implementation ProductRepository as a scoped service:

1
builder.Services.AddScoped<IProductRepository, ProductRepository>();

Finally, we will have an API controller with action methods using the injected Repository to handle the product objects needed for each case.  

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
private readonly IProductRepository _repository;
public ProductsController(IProductRepository repository)
{
_repository = repository;
}
[HttpGet]
public async Task<IReadOnlyList<Product>> GetProducts()
{
return await _repository.GetAllProductsAsync();
}
[HttpGet("{id}")]
public async Task<Product> GetProduct(Guid id)
{
return await _repository.GetProductByIdAsync(id);
}
[HttpPost]
public async Task<Product> CreateProduct(Product product)
{
await _repository.AddProductAsync(product);
return product;
}
[HttpPut]
public async Task<Product> UpdateProduct(Product updatedProduct)
{
await _repository.UpdateProductAsync(updatedProduct);
return updatedProduct;
}
[HttpDelete("{id}")]
public async Task<bool> DeleteProduct(Guid id)
{
var product = await _repository.GetProductByIdAsync(id);
await _repository.DeleteProductAsync(id);
return true;
}
}

Integration of Swagger

The following section covers the integration of Swagger in an existing .Net Core API, specifically the product catalog API. We will start with the basic setup at the beginning and then will have a look at some custom features from Swagger that can be added.

1. Install Swagger NuGet Package

The Swashbuckle.AspNetCore package provides the tools to integrate Swagger into your .NET Core API. You need to navigate to the project directory and run the command:

1
dotnet add package Swashbuckle.AspNetCore –version 6.7.0

2. Register the SwaggerGen Service

Then, you should add the SwaggerGen for the OpenApi specification to automatically generate API documentation for the product catalog app. Further, create a document with a meaningful name, title, and version instead of using the default settings.

12345678
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc(name: "v1", new Microsoft.OpenApi.Models.OpenApiInfo()
{
Title = "Product Catalog",
Version = "v1"
});
});

The name and the version must be the same when we set a SwaggerDoc. Swagger will organize and display the documentation based on this, ensuring that we can see the correct API version.

3. Enable Swagger Middleware

We will enable both the Swagger JSON endpoint and the Swagger UI, configuring Swagger Middlewares. We can set the RoutePrefix to an empty string, as it makes the Swagger UI accessible from the root URL.

1234567
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.RoutePrefix = string.Empty;
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Product Catalog API V1");
});
How to Integrate Swagger for API Documentation in .NET Core?
This brief guide will help you organize your work with Swagger.
Read the guide

4. Get Access to Swagger UI

Everything is ready now. To view the Swagger UI, we can navigate to https://localhost:<port>:

Overview of Swagger setup in .NET Core for a product catalog API

The swagger.json endpoint listens to http://localhost:<port>/swagger/v1/swagger.json:

Swagger integration with .NET Core API for product catalog management

5. Enhance Documentation with XML Comments

Some action methods may need further explanation. Triple-slash comments to the section header of each method will enhance the Swagger UI and the implementation will be clearer to the consumer. To enable XML Comments:

  • Right Click on the API Project in Visual Studio and click Properties
  • In Build Tab -> Output -> check the Documentation file.
Example of Swagger documentation in .NET Core product catalog API
  • In Build Tab -> Errors and Warnings -> Suppress 1591 that gives warnings to any method, class, or field that doesn’t have triple-slash comments.
  • Include the generated XML documentation file in Swagger:
123456789101112
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc(name: "v1", new Microsoft.OpenApi.Models.OpenApiInfo()
{
Title = "Product Catalog",
Version = "v1"
});
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);
});
  • Add a summary to describe the GetProducts method to see what will be displayed on the Swagger UI:
123456789
/// <summary>
/// Retrieves the list of all products.
/// </summary>
/// <returns>A readonly list of products.</returns>
[HttpGet]
public async Task<IReadOnlyList<Product>> GetProducts()
{
return await _repository.GetAllProductsAsync();
}

As you can see, this summary will appear next to the HttpGet action method, providing users with a clear description of its functionality.

API documentation for product catalog using Swagger and .NET Core

6. Apply Data Annotations for Validation

To ensure proper validation in our .NET Core application, we can use data annotations. Let’s make the name property required. The Swagger UI will identify this change and mark the name as mandatory.

Add the [Required] attribute to the Name property of the Product Class:

12345678910111213
public class Product
{
public Guid Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
}

Check the Product Schema to see the Swagger UI change:

Visualizing .NET Core product catalog API with Swagger integration

A red asterisk appeared next to the name. It indicates that it is required to add the name.

7. Secure Swagger Endpoints with API Key

The product catalog API is accessible to anyone with this implementation so far. But we need to provide access only to those clients that have the necessary rights. OpenAPI supports various security schemes to do this. We will use an API key to authenticate requests. 

To enable the api-key mechanism, we will create and register a custom middleware. This will extract the X-API-KEY header from incoming requests and compare it against the key defined in appsettings.json. Let’s start:

  • An API key will be stored in appsetting.json:
123
{
"ApiKey": "your-secret-api-key"
}
  • The implementation of the API key middleware can be performed the following way:
1234567891011121314151617181920212223
public class ApiKeyMiddleware
{
private readonly RequestDelegate _next;
private const string APIKEY_HEADER = "X-API-KEY";
public ApiKeyMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, IConfiguration configuration)
{
if (!context.Request.Headers.TryGetValue(APIKEY_HEADER, out var extractedApiKey) ||
!configuration.GetValue<string>("ApiKey").Equals(extractedApiKey))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Unauthorized client.");
return;
}
await _next(context);
}
}
  • Now, let’s add the custom middleware to the request pipeline on program.cs:
1
app.UseMiddleware<ApiKeyMiddleware>();

Next, we need to integrate this security mechanism into Swagger. Let’s add SecurityDefinition and SecurityRequirement:

12345678910111213141516171819202122232425262728293031323334353637
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc(name: "v1", new Microsoft.OpenApi.Models.OpenApiInfo()
{
Title = "Product Catalog",
Version = "v1"
});
options.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
{
Name = "X-API-KEY",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "ApiKeyScheme"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "ApiKey"
},
Scheme = "ApiKeyScheme",
Name = "X-API-KEY",
In = ParameterLocation.Header
},
new List<string>()
}
});
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
options.IncludeXmlComments(xmlPath);
});

After that Swagger will add an Authorize button on the top right corner of its UI. The user can enter a valid API key to be sent with future requests.

Setting up Swagger for product catalog API in .NET Core framework

By performing these steps, you can make sure that the API is secure. We will need to provide the valid api-key, using the authorize feature on Swagger to interact with our endpoints. Otherwise, it will trigger an Unauthorized client error.

.NET Development Services
Get your full-cycle .NET development services from certified and experienced software engineers.
Book a call

Conclusion

Done! We have successfully integrated Swagger into the product catalog API. In this article, we walked through:

  • Swagger Installation and Setup
  • Documentation Generation
  • XML Comments Integration
  • Application of Data Annotations
  • Security Configurations

By following the provided step-by-step instructions you can ensure smooth integration of Swagger in your own .NET Core software solution.

If you need any technical help or professional consultancy from our .NET experts, do not hesitate to contact us. Over the years of work in the software development industry, we have accumulated unique expertise in various business domains and will be able to cope with any type of tasks.

Subscribe to our newsletter and get amazing content right in your inbox.

This field is required
This field is required Invalid email address
By submitting data, I agree to the Privacy Policy

Thank you for subscribing!
See you soon... in your inbox!

confirm your subscription, make sure to check your promotions/spam folder

Tags

Subscribe to our newsletter and get amazing content right in your inbox.

You can unsubscribe from the newsletter at any time

This field is required
This field is required Invalid email address

You're almost there...

A confirmation was sent to your email

confirm your subscription, make sure to check
your promotions/spam folder