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:
-
Own its domain data: Each service will have exclusive write access to its data, with other services accessing data through defined interfaces.
-
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
-
Define explicit interfaces: Services will expose well-defined APIs (both synchronous and event-driven) for other services to interact with.
-
Maintain independence: Services will be independently deployable and scalable.
-
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
-
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¶
-
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
-
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
-
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