StartXKit docs
Architectures

Layered Architecture

A responsibility-first layout for larger APIs with clear boundaries between routes, controllers, services, and repositories.

Layered architecture organizes code by responsibility.

Instead of placing all users files in one folder, each type of file has a top-level folder. Routes go in src/routes, controllers go in src/controllers, services go in src/services, and repositories go in src/repositories.

When To Use Layered

Use layered when:

  • The API has many features
  • The team wants strict boundaries between responsibilities
  • Business logic should be easy to test outside HTTP
  • Data access should be isolated behind repositories
  • You want a structure that scales as the project grows

Structure

src/
  server.ts
  routes/
    health.route.ts
    users.route.ts
  controllers/
    health.controller.ts
    users.controller.ts
  services/
    health.service.ts
    users.service.ts
  repositories/
    health.repository.ts
    users.repository.ts
  interfaces/
    health.interface.ts
    users.interface.ts
  validators/
    health.validation.ts
    users.validation.ts
  shared/
  config/

Request Flow

Request
  |
  v
route
  |
  v
controller
  |
  v
service
  |
  v
repository
  |
  v
Response

Layer Responsibilities

LayerResponsibilityShould avoid
RouteHTTP path registrationBusiness rules
ControllerRequest and response handlingData persistence details
ServiceBusiness rules and orchestrationFramework-specific request objects
RepositoryData access boundaryHTTP response formatting
InterfaceTypeScript contractsRuntime logic
ValidatorValidation schemas or helpersBusiness orchestration

Add-Module Depth

Layered projects still let you choose how much of the stack to generate:

ChoiceFiles
Route + Controllerroutes, controllers
Route + Controller + Serviceroutes, controllers, services
Route + Controller + Service + Repositoryroutes, controllers, services, repositories
FullAll layers, including interfaces and validators

Why Use Layered

Layered projects make dependencies visible:

controller depends on service
service depends on repository
repository does not depend on controller

That direction matters. It keeps business logic away from framework-specific HTTP details and makes service tests easier to write later.

Trade-Off

Layered creates more files. For a tiny API, that can feel heavy. For a growing production API, the extra structure usually pays for itself through clearer ownership and easier testing.