Skip to content

Conversation

@allisson
Copy link
Owner

@allisson allisson commented Jan 24, 2026

Complete architectural refactoring to establish a scalable, maintainable
codebase using modular domain-driven design principles with proper
separation of concerns between internal models and API contracts.

Key Changes:

  1. Modular Domain Structure
    • Reorganize from flat layer-based to domain-based modules
    • Create self-contained user/ and outbox/ domain modules
    • Each domain has its own domain/, usecase/, repository/, http/ layers
    • Co-locate related code for improved maintainability
  2. Shared HTTP Utilities
    • Extract common JSON response handling to internal/httputil
    • Provide public MakeJSONResponse API for all domains
    • Eliminate code duplication across HTTP handlers
    • Ensure consistent response formatting
  3. Data Transfer Objects Pattern
    • Introduce internal/user/http/dto with request/response DTOs
    • Separate internal domain models from external API contracts
    • Remove JSON tags from domain entities (pure business models)
    • Add validation at DTO level with explicit mapper functions
    • Prevent sensitive field exposure in API responses

Benefits:

  • Scalable architecture - easy to add new domains independently
  • Clean separation - domain models decoupled from API serialization
  • Code reuse - shared utilities eliminate duplication
  • Security - explicit field mapping prevents data leakage
  • Maintainability - related code co-located, clear boundaries
  • Team collaboration - teams can work on different domains in parallel
  • Flexibility - API contracts evolve independently from domain logic

BREAKING CHANGE: Import paths have changed from internal/{domain,usecase,
repository,http} to internal/{domain}/{domain,usecase,repository,http}.
External consumers must update imports.

Restructure the project to use a modular domain-driven architecture where
each business domain is self-contained with its own domain, usecase,
repository, and HTTP layers. This improves scalability, maintainability,
and team collaboration for larger projects.

BREAKING CHANGE: Package structure has changed from flat layers to
domain-based modules. Import paths need to be updated for any external
consumers.

Changes:
- Reorganize internal/ structure into domain modules (user/, outbox/)
- Move user entities from internal/domain to internal/user/domain
- Move user use cases from internal/usecase to internal/user/usecase
- Move user repository from internal/repository to internal/user/repository
- Move user HTTP handler from internal/http to internal/user/http
- Move outbox entities from internal/domain to internal/outbox/domain
- Move outbox repository from internal/repository to internal/outbox/repository
- Update all imports to use aliased domain-specific imports
- Update main.go to use new import paths with aliases
- Update HTTP server to use user HTTP handler from new location
- Update worker to use outbox domain from new location
- Update all test files with new import paths
- Refactor response utilities in internal/http for shared use
- Update README.md with new architecture documentation

Benefits:
- Easy to add new domains without affecting existing code
- Clear domain boundaries and encapsulation
- Related code is co-located within domain modules
- Better support for team collaboration on different domains
- Scalable structure suitable for growing applications

New structure:
internal/
├── config/          # Shared configuration
├── database/        # Shared database infrastructure
├── http/            # Shared HTTP server and middleware
├── outbox/          # Outbox domain module
│   ├── domain/
│   └── repository/
├── user/            # User domain module
│   ├── domain/
│   ├── http/
│   ├── repository/
│   └── usecase/
└── worker/          # Shared background worker
Extract JSON response handling into a dedicated httputil package to
promote code reuse and eliminate duplication across domain modules.
This allows all HTTP handlers to use a consistent, public API for
response formatting.

Changes:
- Create new internal/httputil package for shared HTTP utilities
- Move MakeJSONResponse from internal/http to internal/httputil
- Make MakeJSONResponse function public (capitalized)
- Add comprehensive tests for httputil package
- Update internal/http/response.go to wrap httputil.MakeJSONResponse
- Update internal/http/middleware.go to use MakeJSONResponse
- Update internal/user/http/user_handler.go to use httputil.MakeJSONResponse
- Remove duplicate makeJSONResponse implementation from user handler
- Update internal/http/http_test.go to use httputil.MakeJSONResponse
- Update README.md with httputil documentation and usage examples

Benefits:
- Single source of truth for JSON response handling
- Public API accessible from any package (no import cycles)
- Eliminates code duplication across domain modules
- Consistent response formatting across all endpoints
- Well-tested shared utility with 100% coverage
- Clear separation of concerns (utilities vs infrastructure)
Introduce Data Transfer Objects (DTOs) to enforce clear boundaries between
internal domain models and external API contracts. This architectural
improvement enhances security, maintainability, and flexibility.

Changes:
- Create internal/user/http/dto package with request, response, and mapper
- Add RegisterUserRequest DTO with validation logic
- Add UserResponse DTO excluding sensitive fields (password)
- Add mapper functions to convert between DTOs and domain/usecase models
- Update user_handler.go to use DTOs instead of exposing domain models
- Remove JSON tags from User domain entity (internal/user/domain/user.go)
- Update tests to use DTOs for API requests and responses
- Add comprehensive DTO pattern documentation to README.md

Benefits:
- Domain models now purely represent internal business entities
- Sensitive fields never exposed in API responses
- API contracts can evolve independently from domain models
- Request validation happens at the DTO level
- Enables multiple API versions with different DTOs
- Improved security through explicit field mapping

The User entity no longer has JSON serialization tags, making it a true
domain model decoupled from presentation concerns. HTTP handlers now use
purpose-built DTOs that explicitly define the API contract.
@allisson allisson changed the title refactor: modularize domains for scalable architecture feat: implement modular domain architecture with DTO pattern Jan 24, 2026
@allisson allisson merged commit 21653cf into main Jan 24, 2026
1 check passed
@allisson allisson deleted the improve-template branch January 24, 2026 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant