🚀 Quick Win: Build a production-ready Web API using the latest C# 13 and .NET 10 features. Includes OpenAPI, rate limiting, and health checks.
Start a new API project with the latest and greatest.
🚀 Create Project
# Create Web API dotnet new webapi -n ModernAPI -minimal cd ModernAPI # Add packages dotnet add package Microsoft.EntityFrameworkCore dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL dotnet add package Microsoft.AspNetCore.OpenApi dotnet add package Swashbuckle.AspNetCore dotnet add package Asp.Versioning.Mvc.ApiExplorer
💡 Program.cs
using Microsoft.EntityFrameworkCore;
using ModernAPI.Models;
using ModernAPI.Services;
var builder = WebApplication.CreateBuilder(args);
// ✅ C# 13: Primary constructor
builder.Services.AddScoped<IProductService, ProductService>();
// ✅ Database with C# 13 features
builder.Services.AddDbContext(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
// ✅ Rate limiting
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("Default", opt =>
{
opt.PermitLimit = 100;
opt.Window = TimeSpan.FromMinutes(1);
});
});
// ✅ OpenAPI with versioning
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddApiVersioning(options =>
{
options.DefaultApiVersion = new Asp.Versioning.ApiVersion(1, 0);
options.AssumeDefaultVersionWhenUnspecified = true;
options.ReportApiVersions = true;
});
// ✅ Health checks
builder.Services.AddHealthChecks()
.AddDbContextCheck();
var app = builder.Build();
// ✅ Pipeline
app.UseHttpsRedirection();
app.UseRateLimiter();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.MapHealthChecks("/health");
// ✅ C# 13: Collection expressions for endpoints
var endpoints = new[]
{
"/api/products",
"/api/orders",
"/api/customers"
};
// ✅ C# 13: Minimal API with primary constructor
app.MapGet("/api/products", async (IProductService service) =>
{
var products = await service.GetProductsAsync();
return Results.Ok(products);
})
.WithName("GetProducts")
.WithOpenApi()
.RequireRateLimiting("Default");
app.MapGet("/api/products/{id:int}", async (int id, IProductService service) =>
{
var product = await service.GetProductAsync(id);
return product is null ? Results.NotFound() : Results.Ok(product);
})
.WithName("GetProduct")
.WithOpenApi();
app.MapPost("/api/products", async (CreateProductRequest request, IProductService service) =>
{
// ✅ C# 13: Required members validation
var product = await service.CreateProductAsync(request);
return Results.Created($"/api/products/{product.Id}", product);
})
.WithName("CreateProduct")
.WithOpenApi()
.RequireRateLimiting("Default");
app.Run();
