Employee Management API
A production-shaped web API: validated, paged, documented, secured, backed by a real database and covered by tests.
The brief
What the finished thing needs to do.
- CRUD endpoints for employees and departments
- Paged, filterable and sortable list endpoints
- Validation returning field-level errors in one consistent shape
- Consistent error responses that never leak internal detail
- Authentication, with authorization on write operations
- OpenAPI documentation generated from the code
- Relational storage with migrations under version control
- Integration tests covering the main paths and the failure paths
How to structure it
Three layers with dependencies pointing inwards. Controllers handle HTTP and nothing else. A service layer holds the business rules and has no knowledge of HTTP. A data layer handles persistence.
DTOs at the boundary, always. Entities never appear in a request or response, so the database schema is free to change without altering the public contract.
One error shape for every failure, defined once and applied through middleware rather than repeated in each controller.
The service layer depends on an interface for data access, which is what makes it testable without a database.
Why these technologies
- ASP.NET Core
- Routing, model binding, validation and dependency injection are provided rather than assembled.
- EF Core with migrations
- Schema changes become reviewable code, and queries stay type-checked.
- DTOs separate from entities
- Prevents the database schema from becoming the public API contract.
- Central exception middleware
- One place that decides what a failure looks like to a caller.
- Integration tests over a real database
- Unit tests cannot catch wiring, migration or query mistakes.
Build it in this order
Each stage produces something that works. That matters — a project that only runs at the very end is a project people abandon.
Project skeleton
One endpoint returning fixed data. Confirm it runs and responds.
Model and database
Entities, DbContext, first migration. Employees and departments with a relationship.
Read endpoints
Get one, get many. Project to DTOs from the start rather than retrofitting.
Write endpoints
Create, update, delete, with correct status codes for each outcome.
Validation
Field-level errors, in the shape you have documented.
Central error handling
Middleware producing consistent responses, with internal detail logged rather than returned.
Pagination, filtering, sorting
On the list endpoint. Cap the page size so a caller cannot request everything.
Authentication and authorization
Require a token; restrict writes to permitted callers.
OpenAPI documentation
Ensure the generated document reflects the real contract, including error shapes.
Integration tests
Exercise the running application over HTTP, including unauthorised and invalid requests.
Fix the N+1 query
Inspect the generated SQL on the list endpoint. There is very likely one to find.
Done means
How to know it is finished
Check each of these before moving on. If one fails, the project is not done yet — and that is useful information rather than a setback.
- Every endpoint returns an appropriate status code for success and each failure mode
- Validation errors identify the specific fields at fault
- No endpoint returns an entity, only DTOs
- List endpoints are paged with an enforced maximum page size
- Write operations reject unauthenticated and unauthorised callers
- The OpenAPI document matches actual behaviour
- Tests cover the main paths and the failure paths
- The list endpoint issues a bounded number of queries regardless of result count
If you want to go further
Extensions worth attempting
Only once the core build meets every criterion above.
- Add API versioning and introduce a breaking change without disrupting v1
- Add caching on read-heavy endpoints and handle invalidation
- Add rate limiting and health check endpoints
- Add an audit trail recording who changed what
- Containerise it and deploy with an automated pipeline
Other projects at this level
Employee Management Console Application
The C# course project. Build it with what you know early, then deliberately refactor it as the language gives you better tools.
Blog API
A smaller API focused on relationships, slugs, publishing state and search.
Inventory Management System
A data-focused build: stock levels, movements, concurrency and reporting that must stay correct under simultaneous use.
Have a project worth talking through?
Tell us what you're building or what's slowing your current system down. We'll give you a direct read on scope and approach.