Skip to content

ADR-0004: Service Boundary Definition

Status

PROPOSED

Date: 2025-07-05

Changelog

Date Revision Description Author
2025-07-05 1.0 Initial version souperk

Context

The Loryth project is being developed as a distributed system with multiple services. Currently, we have placeholder services (budget, cms, issues, journal) without clearly defined boundaries. Proper service boundary definition is crucial for:

  • Maintaining loose coupling between services
  • Enabling independent deployment and scaling
  • Facilitating team autonomy
  • Ensuring appropriate data ownership
  • Providing clear responsibilities for each service

Without well-defined service boundaries, we risk creating a distributed monolith with tight coupling, unclear responsibilities, and operational challenges.

Decision

We will define service boundaries based on domain-driven design principles, specifically focusing on bounded contexts. Each service will:

  1. Own its domain data: Each service will have exclusive write access to its data, with other services accessing data through defined interfaces.

  2. Have a single responsibility: Each service will focus on a specific domain area:

    • Budget Service: Manage financial planning, expense tracking, and budget analysis
    • CMS Service: Handle content creation, publishing, and management
    • Issues Service: Track problems, tasks, and work items through their lifecycle
    • Journal Service: Record and query event logs and audit information
  3. Define explicit interfaces: Services will expose well-defined APIs (both synchronous and event-driven) for other services to interact with.

  4. Maintain independence: Services will be independently deployable and scalable.

  5. Interaction patterns:

    • Services will communicate primarily through events for state changes (following ADR-0003)
    • Direct synchronous calls will be limited to query operations where eventual consistency is not acceptable
    • Each service will implement appropriate caching strategies for frequently accessed data from other services
  6. Data duplication: We accept limited data duplication across services to maintain service independence:

    • Reference data may be duplicated with clear ownership boundaries
    • Read-only projections of data from other services may be maintained for query performance

Consequences

Positive

  • Clear responsibilities: Each service has a well-defined area of responsibility
  • Team autonomy: Teams can work independently on different services
  • Deployment flexibility: Services can be deployed and scaled independently
  • Technology flexibility: Different services can use different technologies as appropriate
  • Resilience: Problems in one service are less likely to impact others

Negative

  • Distributed transactions: More complex handling of operations that span multiple services
  • Operational complexity: Managing multiple services increases operational overhead
  • Data consistency challenges: Eventual consistency requires careful design consideration
  • Learning curve: Teams need to understand domain-driven design principles

Neutral

  • API governance: Will require ongoing attention to maintain consistent API design across services
  • Service discovery: Additional infrastructure needed for service discovery and communication
  • Documentation importance: Increased importance of interface documentation and contracts

Alternatives Considered

  1. Monolithic Architecture

    • Description: Single application with internal modules instead of separate services
    • Pros:
      • Simpler development and deployment
      • Direct method calls instead of network communication
      • Transactional consistency across modules
    • Cons:
      • Limited independent scaling
      • Potential for tight coupling between modules
      • All-or-nothing deployment increases risk
    • Why not chosen: Would limit our ability to scale and evolve the system independently
  2. Functional Service Boundaries

    • Description: Define services based on technical function rather than domain
    • Pros:
      • Clear technical specialization
      • Potentially more reusable services
    • Cons:
      • Multiple services needed for a single business capability
      • Business logic spread across services
      • More complex coordination for business operations
    • Why not chosen: Would lead to fragmented business logic and increased coordination complexity
  3. Microservice per Entity

    • Description: Very fine-grained services, one per major entity
    • Pros:
      • Maximum flexibility and scaling granularity
      • Very clear data ownership
    • Cons:
      • Excessive operational overhead
      • Too many network hops for common operations
      • Complex orchestration for business processes
    • Why not chosen: Would introduce unnecessary complexity and performance overhead

References