Skip to main content

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