DEV Community

Jose Manuel Castellano Jiménez
Jose Manuel Castellano Jiménez

Posted on

Best hexagonal course ever

Excellent choice! This repository is a very well-structured **production architecture reference.

ecotrack Java Application Repo

Suggested Study Plan

1. Start with the Documentation

docs/
├── learn_hexagonal/learn_hexagonal.md    # START HERE!
├── architecture/C4-containers.md         # High-level view
└── runbook.md                            # Operations
Enter fullscreen mode Exit fullscreen mode

Why: The learn_hexagonal documentation will map out exactly how the concepts we discussed are implemented.

2. Analyze the Structure of ONE Service First

I recommend starting with user-service because it is the simplest:

services/user-service/
├── src/main/java/com/ecotrack/user/
│   ├── domain/          # ← CORE: Entities, Value Objects, Domain Services
│   ├── application/     # ← USE CASES: Application Services, Ports
│   ├── infrastructure/  # ← ADAPTERS: REST, JPA, Config
│   └── UserServiceApplication.java
Enter fullscreen mode Exit fullscreen mode

3. Practical Hexagonal Mapping

Domain (Center of the Hexagon):

// services/user-service/src/main/java/com/ecotrack/user/domain/
├── User.java              # Main entity
├── UserRepository.java    # Port (interface) - NO implementation
├── Email.java             # Value Object
└── UserDomainService.java # Complex domain logic
Enter fullscreen mode Exit fullscreen mode

Application (Use Cases):

// services/user-service/src/main/java/com/ecotrack/user/application/
├── CreateUserUseCase.java     # Use case
├── FindUserUseCase.java       # Another use case
└── ports/
    ├── in/                    # Input ports (what the domain exposes)
    └── out/                   # Output ports (what the domain needs)
Enter fullscreen mode Exit fullscreen mode

Infrastructure (Adapters):

// services/user-service/src/main/java/com/ecotrack/user/infrastructure/
├── web/
│   └── UserController.java    # REST Adapter (IN Port)
├── persistence/
│   └── JpaUserRepository.java # JPA Adapter (OUT port)
└── config/
    └── BeanConfiguration.java # Dependency injection
Enter fullscreen mode Exit fullscreen mode

4. Data Flow to Follow

  1. HTTP Request → UserController (Adapter)
  2. Controller → CreateUserUseCase (Application)
  3. Use Case → UserDomainService (Domain)
  4. Domain → UserRepository interface (Port)
  5. Interface → JpaUserRepository (Adapter)
  6. JPA → PostgreSQL

5. Key Concepts to Look For

Dependency Injection:

@Component
public class CreateUserUseCase {
    private final UserRepository userRepository; // Port, not implementation

    public CreateUserUseCase(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}
Enter fullscreen mode Exit fullscreen mode

Configuration (Composition Root):

@Configuration
public class BeanConfiguration {
    @Bean
    public UserRepository userRepository() {
        return new JpaUserRepository(); // Here the adapter connects to the port
    }
}
Enter fullscreen mode Exit fullscreen mode

6. Compare with the CQRS Diagram

The project probably implements:

  • Commands: CreateUserUseCase, UpdateUserUseCase
  • Queries: FindUserUseCase, GetUserProfileUseCase
  • Events: See tracking-service using Kafka

7. Layered Learning Approach

Week 1: A single service (user-service)

  • Folder structure
  • HTTP flow → Domain → DB
  • Testing each layer

Week 2: Communication between services

  • tracking-service → Kafka → notification-service
  • Events and asynchronous messaging

Week 3: Infrastructure & DevOps

  • Docker Compose setup
  • Kubernetes manifests
  • Observability (metrics, logs)

8. Suggested Practical Exercises

  1. Map the complete flow of creating a user
  2. Add a new endpoint following the same pattern
  3. Write tests for each layer separately
  4. Modify the implementation of persistence (change from JPA to something else)

9. Questions to Ask Yourself

  • Where are the business rules?
  • How are dependencies injected?
  • What would happen if I replaced PostgreSQL with MongoDB?
  • How is each layer tested independently?
  • How do services communicate with each other?

10. Red Flags to Avoid

  • Don't copy code without understanding why it's there
  • Don't implement all services at once
  • Don't ignore tests—they reveal a lot about the architecture
  • Don't skip the learn_hexagonal documentation

Tip: After you understand a service well, try to recreate the structure from scratch with a different domain (e.g., a library, a simple e-commerce site). This will confirm that you really understood the patterns.

Which service would you like to start with? I strongly recommend user-service because it is the most straightforward for understanding the fundamentals.

Translated with DeepL.com (free version)

Top comments (0)