4) Practical Tutorial — Building a REST API with .
NET (Minimal example)
---
title: "Building a REST API with .NET — Practical Tutorial"
author: "Prepared for Scribd"
date: "2025-09-11"
---
# Building a REST API with .NET (Minimal, production-minded)
## 1. Project Setup
```bash
dotnet new webapi -n TodoApi
cd TodoApi
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Swashbuckle.AspNetCore
2. Folder structure (recommended)
/Controllers
/Models
/Data
/DTOs
/Services
/Mapping
/Tests
3. Example Model & DTO
// Models/TodoItem.cs
public class TodoItem {
public int Id { get; set; }
public string Title { get; set; } = "";
public bool IsCompleted { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}
// DTOs/TodoCreateDto.cs
public record TodoCreateDto(string Title);
4. DbContext
Page 1 of 3
public class AppDbContext : DbContext {
public DbSet<TodoItem> Todos { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) :
base(options) { }
}
5. Minimal Controller (Endpoints)
[ApiController]
[Route("api/[controller]")]
public class TodosController : ControllerBase {
private readonly AppDbContext _db;
public TodosController(AppDbContext db) => _db = db;
[HttpGet]
public async Task<IActionResult> Get() => Ok(await
_db.Todos.ToListAsync());
[HttpPost]
public async Task<IActionResult> Create(TodoCreateDto dto) {
var item = new TodoItem { Title = dto.Title };
_db.Todos.Add(item);
await _db.SaveChangesAsync();
return CreatedAtAction(nameof(GetById), new { id = item.Id }, item);
}
[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id) =>
await _db.Todos.FindAsync(id) is TodoItem t ? Ok(t) : NotFound();
}
6. Migrations & Database
dotnet ef migrations add Init
dotnet ef database update
7. Dockerfile (simple)
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
Page 2 of 3
COPY . .
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "TodoApi.dll"]
8. Testing (xUnit simple integration)
Use WebApplicationFactory to run in-memory tests
Test endpoints for 200/201/404 responses and basic behavior
9. Production Considerations
Use DTOs + AutoMapper to avoid over-posting
Implement paging for list endpoints
Rate limiting, logging (Serilog), health checks, proper exception middleware
Secure: TLS, input validation, authentication (JWT + refresh tokens), role-based authorization
10. CI/CD checklist
Run unit & integration tests
Static analysis (Roslyn analyzers)
Build + push container to registry
Apply infrastructure as code (Terraform / Bicep)
Page 3 of 3