Files
2025-11-30 08:57:06 +08:00

3.0 KiB

name, description, license
name description license
backend-code-organisation Kotlin backend layering and packaging guidelines MIT

Mission

  • Keep backend services modular: resources handle transport, managers own business logic, and data access stays isolated.
  • Maintain clean dependency flow across modules (servicecoremodels) to encourage reuse and testability.

Layering Principles

  • Resources: Only translate HTTP/storage inputs to domain calls. No database or cross-service logic. Convert SecurityContext early.
  • Managers: Encapsulate business rules; coordinate helpers, other managers, workflows, and DAL components. Break cycles by separating read/write responsibilities or introducing controllers.
  • Helpers/Services: Reusable integrations (feature flags, external clients). Centralize external service calls to simplify retries and upgrades.
  • Repos/DAL/DAO: Keep database interactions single-purpose. Compose multi-step transactions in repos/DAL; keep DAO calls single query.
  • Utils/Validators/Transformers: Pure functions and extensions only; avoid hidden state.
  • Cache Managers: Inject Redis/Lettuce clients, expose typed get/invalidate helpers.

Package & Module Structure

  • Enforce lowercase package names without underscores; avoid versioned package hierarchies (v2 folders). Prefer managers.slots over managers.slots.v2.
  • Organize by responsibility: managers, helpers, utils, dao, workflows, etc. Mirror structure in tests.
  • Module boundaries:
    • core: managers, helpers, data access, transient models. May depend on models.
    • service: Dropwizard resources, configuration, application wiring; no direct DB access.
    • console-service: Console-specific resources/auth; depends on core.
    • client: Outbound clients; depend only on models.
    • models: Shared API/data contracts; no dependencies.

Dependency Injection & Config

  • Add new Redis/Cosmos/DB configs across all environments (db-test, db-dev, db-warehouse-prod) and run the service locally to validate.
  • Annotate injectable classes with @Singleton when appropriate.
  • Only use @Named when multiple bindings of the same type exist; otherwise default bindings suffice.
  • Centralize client construction in DI modules to enforce consistent timeouts and hosts.

Review Checklist

  • Check that new features land in the correct layer and module (e.g., resources calling managers, not DAOs).
  • Ensure helpers/managers do not introduce cyclic dependencies; suggest splitting read/write flows or using controller orchestrators.
  • Verify repos/DAL enforce validation and error translation before returning data.
  • Confirm new package or module names remain lowercase and idiomatic; flag attempts to create v2 package forks.
  • Audit DI modules for duplicate provider methods and proper scoping.

Tooling Tips

  • Glob for *.kt within service/ or core/ to inspect layer usage.
  • Read DI modules when new bindings appear to ensure wiring matches guidelines.
  • Grep for @Named or direct DAO usage inside resources to catch misplaced logic.