DevPath · Learn to code ESPTEN

Data, ORMs and layered architecture

Layered architecture

Separating responsibilities

A maintainable backend application separates code into layers, each with a single responsibility. The request crosses them from outside in:

HTTP → Controller → Service → Repository → Database

Controller (HTTP)

It is the (req, res) handler. Its only job is to translate HTTP: read req.body/req.params, call the service and respond with the appropriate status and JSON. It contains no business rules or SQL.

async function create(req, res) {
  const user = await service.register(req.body);
  res.status(201).json(user);
}

Service (business logic)

It contains the rules: domain validations, "do not allow duplicate emails", computing totals, orchestrating several repositories. It does not know about req/res or SQL; it asks the repository for data.

async function register(data) {
  const exists = await repo.findByEmail(data.email);
  if (exists) throw new Error("Duplicate email");
  return repo.create(data);
}

Repository (data)

The one you saw before: only data access.

Dependency injection

Notice that the service uses repo and the controller uses service. Instead of creating those dependencies inside (const repo = new SqlRepo()), they are received from outside. That is dependency injection:

function createService(repo) {        // receives the repo as a parameter
  return {
    async register(data) {
      if (await repo.findByEmail(data.email)) {
        throw new Error("Duplicate email");
      }
      return repo.create(data);
    },
  };
}

Advantages: in production you inject the real repository; in tests you inject a mock or an in-memory repo, without touching the service. Each layer is tested in isolation, and the whole stays decoupled and easy to change.

Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
← The Repository patternBeyond the monolith: microservices and events →