Skip to main content
ANVISoftware Solutions

Employee Management API

Intermediate25-35 hours

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.

Layers behind an API endpointA client calls the API. The controller layer handles HTTP concerns only. It delegates to a service layer holding business rules, which uses a data access layer to reach the database. Authentication sits at the boundary before the controller. Dependencies point inwards: the service does not know about HTTP, and the business rules do not know about the database implementation.Clientweb, mobile, serviceAuthenticationwho is calling?ControllerHTTP onlyBusiness logicthe rulesData accessDatabaseBusiness logic has no knowledge of HTTP, which is what makes it testable without a server.

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.

  1. Project skeleton

    One endpoint returning fixed data. Confirm it runs and responds.

  2. Model and database

    Entities, DbContext, first migration. Employees and departments with a relationship.

  3. Read endpoints

    Get one, get many. Project to DTOs from the start rather than retrofitting.

  4. Write endpoints

    Create, update, delete, with correct status codes for each outcome.

  5. Validation

    Field-level errors, in the shape you have documented.

  6. Central error handling

    Middleware producing consistent responses, with internal detail logged rather than returned.

  7. Pagination, filtering, sorting

    On the list endpoint. Cap the page size so a caller cannot request everything.

  8. Authentication and authorization

    Require a token; restrict writes to permitted callers.

  9. OpenAPI documentation

    Ensure the generated document reflects the real contract, including error shapes.

  10. Integration tests

    Exercise the running application over HTTP, including unauthorised and invalid requests.

  11. 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

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.