Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

헥사고날 아키텍처와 마이크로서비스 아키텍처(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)       |
+---------------------+                                  +------------------------+

설명

  1. NotificationService:

    • NotificationService는 비즈니스 로직에서 UserClientPort를 통해 User 정보를 요청합니다.

  2. UserClientPort:

    • Notification Feature의 Outbound Port로서, UserClientAdapter의 호출 인터페이스 역할을 합니다.

  3. UserClientAdapter:

    • UserClientPort를 구현하며, UserServicePort를 호출하여 User 정보를 가져옵니다.

  4. UserServicePort:

    • User Feature의 Inbound Port로서 외부 요청을 처리합니다.

  5. UserServiceImpl:

    • UserServicePort의 구현체로, 비즈니스 로직을 처리하며 JPA Repository(UserRepository)와 상호작용합니다.

...

추가 설명: 인터페이스와 Port

  • **인터페이스(interface)**는 추상화를 제공하는 도구이지만, 무조건 Port로 간주할 수는 없습니다. 헥사고날 아키텍처에서 Port는 Core Domain의 경계를 정의하며 외부와의 상호작용을 추상화하는 데 사용됩니다.

  • UserRepository는 JPA의 인터페이스를 확장한 기술적 세부사항을 포함하며, 이는 헥사고날 아키텍처에서 Adapter의 역할에 해당합니다. Core Domain은 UserRepository를 직접 알지 못하며, 대신 추상화된 Outbound Port를 통해 접근합니다.

...

Port와 Adapter를 사용한 설계의 장점

...