Web APIs
Short Introduction
Web APIs in ASP.NET Core provide a framework for building HTTP-based services that can be consumed by various clients including web applications, mobile apps, and other services.
Official Definition
ASP.NET Core Web API is a framework for building HTTP services that can reach a broad range of clients, including browsers, mobile devices, and traditional desktop applications.
Usage
// API Controller
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IProductService _productService;
private readonly IMapper _mapper;
public ProductsController(IProductService productService, IMapper mapper)
{
_productService = productService;
_mapper = mapper;
}
/// <summary>
/// Gets all products
/// </summary>
/// <returns>List of products</returns>
[HttpGet]
[ProducesResponseType(typeof(IEnumerable<ProductDto>), StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<ProductDto>>> GetProducts()
{
var products = await _productService.GetAllProductsAsync();
var dtos = _mapper.Map<IEnumerable<ProductDto>>(products);
return Ok(dtos);
}
/// <summary>
/// Gets a product by ID
/// </summary>
/// <param name="id">Product ID</param>
/// <returns>Product details</returns>
[HttpGet("{id}")]
[ProducesResponseType(typeof(ProductDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<ProductDto>> GetProduct(int id)
{
var product = await _productService.GetProductByIdAsync(id);
if (product == null)
return NotFound();
var dto = _mapper.Map<ProductDto>(product);
return Ok(dto);
}
/// <summary>
/// Creates a new product
/// </summary>
/// <param name="dto">Product creation data</param>
/// <returns>Created product</returns>
[HttpPost]
[ProducesResponseType(typeof(ProductDto), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<ProductDto>> CreateProduct(CreateProductDto dto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var product = await _productService.CreateProductAsync(dto);
var productDto = _mapper.Map<ProductDto>(product);
return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, productDto);
}
/// <summary>
/// Updates an existing product
/// </summary>
/// <param name="id">Product ID</param>
/// <param name="dto">Product update data</param>
/// <returns>No content</returns>
[HttpPut("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> UpdateProduct(int id, UpdateProductDto dto)
{
if (id != dto.Id)
return BadRequest();
if (!ModelState.IsValid)
return BadRequest(ModelState);
var exists = await _productService.ProductExistsAsync(id);
if (!exists)
return NotFound();
await _productService.UpdateProductAsync(dto);
return NoContent();
}
/// <summary>
/// Deletes a product
/// </summary>
/// <param name="id">Product ID</param>
/// <returns>No content</returns>
[HttpDelete("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> DeleteProduct(int id)
{
var exists = await _productService.ProductExistsAsync(id);
if (!exists)
return NotFound();
await _productService.DeleteProductAsync(id);
return NoContent();
}
}
DTOs (Data Transfer Objects)
public class ProductDto
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
public string Description { get; set; } = string.Empty;
public string CategoryName { get; set; } = string.Empty;
}
public class CreateProductDto
{
[Required]
[StringLength(100)]
public string Name { get; set; } = string.Empty;
[Required]
[Range(0.01, double.MaxValue)]
public decimal Price { get; set; }
[StringLength(500)]
public string Description { get; set; } = string.Empty;
[Required]
public int CategoryId { get; set; }
}
public class UpdateProductDto
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; } = string.Empty;
[Required]
[Range(0.01, double.MaxValue)]
public decimal Price { get; set; }
[StringLength(500)]
public string Description { get; set; } = string.Empty;
[Required]
public int CategoryId { get; set; }
}
API Documentation with Swagger
// Program.cs
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Products API",
Version = "v1",
Description = "API for managing products"
});
// Include XML comments
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Products API V1");
});
}
Use Cases
- Mobile app backends
- Microservices
- Integration with third-party systems
- Single Page Applications (SPAs)
- Inter-service communication