헥사고날 아키텍처와 마이크로서비스 아키텍처(MSA)를 결합하면 시스템의 복잡성을 효과적으로 관리할 수 있습니다. 이 글에서는 Feature 중심 설계와 Port와 Adapter를 활용한 Feature 간 상호작용 방법을 설명합니다.
...
Code Block |
---|
public interface UserServicePort {
UserResponse getUserById(String userId);
}
|
User Feature의 Inbound Port 구현체
UserServicePort
의 구현체는 User
Feature의 데이터 접근 로직을 처리하며, JPA Repository를 사용해 데이터를 관리합니다.
Code Block |
---|
@Service public class UserServiceImpl implements UserServicePort { private final UserRepository userRepository; public UserServiceImpl(UserRepository userRepository) { this.userRepository = userRepository; } @Override public UserResponse getUserById(String userId) { User user = userRepository.findById(userId) .orElseThrow(() -> new RuntimeException("User not found")); return new UserResponse(user.getId(), user.getName(), user.getEmail()); } } |
User Feature의 Repository
JPA를 활용하여 User 데이터를 관리하는 Repository는 다음과 같이 정의됩니다:
Code Block |
---|
public interface UserRepository extends JpaRepository<User, String> {
}
|
Notification Feature의 서비스
...
Code Block |
---|
@Service
public class NotificationService {
private final UserClientPort userClientPort;
public NotificationService(UserClientPort userClientPort) {
this.userClientPort = userClientPort;
}
public NotificationResponse sendNotification(String userId, String message) {
UserResponse user = userClientPort.getUser(userId);
// 비즈니스 로직 수행
return new NotificationResponse("Sent to " + user.getEmail());
}
}
|
...
클래스 간 관계 도식화
Code Block |
---|
[Notification Feature] [User Feature]
+---------------------+ +------------------------+
| NotificationService | | UserServiceImpl |
| (Core Logic) | | (Business Logic) |
+---------------------+ +------------------------+
| |
v |
+---------------------+ Request +------------------------+
| UserClientPort | -------------------------------> | UserServicePort |
| (Outbound Port) | | (Inbound Port) |
+---------------------+ +------------------------+
^ ^
| |
+---------------------+ +------------------------+
| UserClientAdapter | <------------------------------- | UserRepository |
| (Outbound Adapter) | Response | (JPA Repository) |
+---------------------+ +------------------------+
|
설명
NotificationService:
NotificationService
는 비즈니스 로직에서UserClientPort
를 통해 User 정보를 요청합니다.
UserClientPort:
Notification
Feature의 Outbound Port로서,UserClientAdapter
의 호출 인터페이스 역할을 합니다.
UserClientAdapter:
UserClientPort
를 구현하며,UserServicePort
를 호출하여 User 정보를 가져옵니다.
UserServicePort:
User
Feature의 Inbound Port로서 외부 요청을 처리합니다.
UserServiceImpl:
UserServicePort
의 구현체로, 비즈니스 로직을 처리하며 JPA Repository(UserRepository
)와 상호작용합니다.
...
추가 설명: 인터페이스와 Port
**인터페이스(interface)**는 추상화를 제공하는 도구이지만, 무조건 Port로 간주할 수는 없습니다. 헥사고날 아키텍처에서 Port는 Core Domain의 경계를 정의하며 외부와의 상호작용을 추상화하는 데 사용됩니다.
UserRepository는 JPA의 인터페이스를 확장한 기술적 세부사항을 포함하며, 이는 헥사고날 아키텍처에서 Adapter의 역할에 해당합니다. Core Domain은
UserRepository
를 직접 알지 못하며, 대신 추상화된 Outbound Port를 통해 접근합니다.
...
Port와 Adapter를 사용한 설계의 장점
...