Overview
In our Hexagonal Architecture, handlers (Driving Adapters) are organized per module. This ensures that a domain-bounded context (module) contains its own entry points, whether they are HTTP requests, NATS events, or future protocols like gRPC.Directory Structure
Modules follow a strict internal structure where all adapters reside in theadapter/ directory, split into inbound (Driving) and outbound (Driven).
Pattern Explanation
✅ Correct Pattern (Current)
Handlers are part of the module’s adapter layer:internal/modules/leave/adapter/inbound/http/handler.gointernal/modules/leave/adapter/inbound/event/consumer.go
❌ Incorrect Pattern (Avoided)
Grouping all handlers for all modules in a single global directory:internal/adapters/handler/http/leave_handler.gointernal/adapters/handler/http/user_handler.go
Benefits of Module-Local Handlers
- Encapsulation: Everything related to the “Leave” domain is in the
leave/directory. - Ease of Deletion: To remove a feature, you simply delete the module’s directory. No need to hunt for handlers in global folders.
- Independence: Modules can choose different adapter structures if necessary without affecting others.
- Local Context: Handlers have direct access to module-local types and constants.
Module Wiring
Each module’smodule.go is responsible for initializing its own adapters and registering its routes.
Future Protocol Support
When adding support for a new protocol (e.g., GraphQL or gRPC), follow the same pattern:- Create
internal/modules/[module]/adapter/inbound/graphql/ - Implement the resolver/handler there.
- Inject the new adapter in
module.go.