Driving Adapter (REST) → Incoming Port (Interface) → Application Service → Outgoing Port (Interface) ← Driven Adapter (JPA)
// application/service/CreateProductService.java package com.example.application.service; import com.example.application.port.in.CreateProductUseCase; import com.example.domain.model.Money; import com.example.domain.model.Product; import com.example.domain.spi.ProductRepository; import lombok.RequiredArgsConstructor;
record CreateProductCommand(String name, double price, String currency) {} } designing hexagonal architecture with java pdf
// adapters/persistence/JpaProductRepository.java package com.example.adapters.persistence; import com.example.domain.model.Product; import com.example.domain.spi.ProductRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import java.util.Optional; @Component @RequiredArgsConstructor public class JpaProductRepository implements ProductRepository private final SpringDataJpaProductRepository jpaRepository;
@PostMapping("/products") public Product createProduct(@RequestBody CreateProductCommand command) return createProductUseCase.execute(command); Driving Adapter (REST) → Incoming Port (Interface) →
private Product toDomain(ProductJpaEntity entity) ...
@Override public Optional<Product> findById(String id) return jpaRepository.findById(id).map(this::toDomain); record CreateProductCommand(String name
// domain/model/Money.java public record Money(double amount, String currency)