개요

MVA (Minimum Viable Architecture)는 시스템의 필수적인 아키텍처만을 구현하여 빠르고 효율적으로 제품을 시장에 출시하고 사용자 피드백을 받는 접근 방식이다[1]. 이는 효과적인 아키텍처 실험과 밀접하게 연결된다. MVA를 통해 각 실험은 원자성(Atomic), 시기적절함(Timely), 명확성(Unambigous)한 특징을 유지하면서, 최소한의 아키텍처로 실험을 진행하여, 더 큰 아키텍처 변경 전에 필요한 피드백을 신속하게 얻을 수 있다. 이러한 접근 방식은 리스크를 최소화하고, 결과의 해석을 간단하게 하며, 전체 개발 과정을 더욱 효과적으로 관리할 수 있도록 돕는다.

 

효과적인 아키텍처 실험의 특징

특징설명

원자성 한 번에 하나의 질문에 집중하여 혼란을 방지하고 결과를 명확하게 한다.
시기 적절함 위험을 작고 관리 가능한 단위로 나누어 빠르게 피드백을 얻고 결과 해석을 간소화한다.
명확성 명확한 성공 기준과 측정 가능한 결과를 가지고 있어 실험이 성공했는지 판단할 수 있다.

 

효과적인 아키텍처 실험을 위한 질문

아래 표는 기사에서 설명하는 효과적인 아키텍처 실험을 수행하는 핵심 원칙을 요약하고, 이러한 실험을 계획하고 실행하기 위한 구조적 접근 방식을 제공한다.

가설 설정
(A clear hypothesis)
우리가 테스트하는 구체적인 가설은 무엇이며, 어떤 결과가 가설이 유효하다는 것을 나타낼까?
측정 가능성
(An explicit and measurable goal or target)
성공을 어떻게 측정할 것이며, 어떤 메트릭을 사용할까?
구현
(A method for running the experiment and mechanisms for measuring its success or failure)
실험을 수행하기 위해 어떤 단계를 밟을 것이며, 결과를 어떻게 문서화할까?
대체 계획
(A plan for rollback if the experiment fails)
실험이 실패할 경우, 우리의 롤백 계획은 무엇인가?
시간
(An explicit timeline for the experiment)
이 실험을 완료해야 하는 시간 프레임은 무엇이며, 우리의 목표와 어떻게 일치해야 하는가?

 

참고 문서

[1] Pierre Pureur and Kurt Bittner, "Software Architecture and the Art of Experimentation", Dec 17, 2024, https://www.infoq.com/articles/architecture-experimentation/?utm_source=infoqEmail&utm_medium=editorial&utm_campaign=ArchitectNL&utm_content=01312025

개요

소프트웨어 아키텍처에 대해서 학습을 하다가 보면, 정말 많은 문서 작업을 요구한다. 정말 이런 것들이 다 필요한 것일까? 정말 다 줄이고 하나만 남긴다면 무엇을 할 수 있을까? 아니면 아예 문서 작업을 하지 않으려 한다면 그래도 이건 꼭 해보자면 무엇을 이야기할 수 있을까?

애자일 하게 개발을 진행하는 조직에서 요구 사항도 취합되어 백로그에 유저 스토리들이 쌓여 있다고 해보자. 이렇게 개발하다 보면, 자연 스럽게 개발자 수준에서 설계도 되어 우리 팀의 아키텍처가 내재되어 나오게 된다. 

하지만, 위의 상황은 상당히 이상적이다. 여러 담당자들이 구현을 해 가다 보면, 이상하다고 느껴지는 부분이 생기곤 한다. 진행이 안되고 막혀 있다는 부분이 있다. 이러한 부분은 의사 결정이 필요할 수도 있고, 실험을 통해서 확인이 필요할 수도 있다. 여기서는 의사 결정을 해야 하는 경우에 대해서 다뤄보자. 이를 위한 것이 아키텍처 의사 결정이고 이를 기록하는 것이 아키텍처 의사 결정 레코드 (Architectural Decision Record)이다.

이렇게 Architect는 의사 결정자나 이해관계자(Stakeholder)가 결정할 수 있또록 정보를 제공하여 결정을 지원하거나, 책임이 자신에게 있다면 기술적인 결정을 해야 한다. 그렇다면, 무엇을 가지고 어떻게 할 수 있을까?

아키텍처 의사 결정 기록 (ADR)소개

이와 같은 경우를 위해 활용할 수 있는 것이 다음과 같은 아키텍처 의사 결정 기록(Architectural Decision Record, ADR)이다. [1]에서는 ADR의 아주 간단한 형식을 보여 준다.

[기능 또는 컴포넌트]에 해당하는 맥락에서,
[요구 사항 또는 목표로 하는 품질 속성(Quality Attribute)]을 충족할 필요가 있다,
우리는 [이익]을 우선적으로 달성하기 위해
[선택된 옵션]을 채택하기로 결정하고
그리고 [대안]은 선택하지 않아서
그 선택에 따르는 [부정적인 결과]는 받아들인다.

이 내용은 아주 간단하게 기술되어 있다. 그렇기 때문에 다음과 같이 나누어 상세 한 부분을 살펴 볼 수 있다.

  • Problem Statement: "[기능 또는 컴포넌트]에 해당하는 맥락에서,"가 이 부분이다. 우리가 결정이 필요한 문제가 어떤 것인지 말한다. 위의 예에서는 간단하게 되어 있지만, 맥락을 잘 표현하기 위해서 더 상세히 설명해야 할 수도 있다.
  • Candidate Architecture: 위의 예에서는 [선택된 옵션]과 [대안]이 여기에 포함된다. 위의 예어서는 2개만 표현되어 있지만 3개 이상일 수 있다. 특히, 옵션들은 정말로 어떤 것을 선택할지 고민이 된다면 중요한 Architecture Problem일 수 있다.
  • 요구 사항 및 품질 속성: 많은 경우, Problem Statement에 우리가 다루려고 하는 Functional Scenario가 이미 포함된다. 아키텍처 선택을 할 때 우리가 고려해야 하는 품질 속성의 중요도에 따라 의사 결정을 하는 것이 일반적이다.
  • 보완 필요 부분: "부정적인 결과"를 받아 들인다고 했다. 하지만, 이 부분이 늘 쉽지는 않다. 그렇기 때문에 이 부정적인 결과에 대한 대책이 필요하기도 하다.

패턴들의 구조에서도 설명되지만 문제 기술도 필요하다. 위의 구조와 유사하지만 다음과 같은 형태도 사용한다

다른 형태의 ADR

위와 같이 간단한 형태에서 상세 내용을 기반으로 조정한 ADR이 포함해야 하는 항목을 다시 한번 정리해 보자.

Problem Statement

이 부분을 분리하는 경우는 ADR이 다루려고 하는 문제를 더 상세히 표현하려고 할 때 분리해서 설명하면 좋다. 그렇지 않고, 간단한 문장으로도 표현할 수 있다.

Candidate Architectures

우리가 실제로 고민해야 하는 Architecture적으로 중요한 결정 사항은 무엇일까? 대안들이 2개 이상일 때 Architecture 적으로 중요한 문제일 수 있다. 예를 들어 보자. 어려 이해관계자들이 요구 사항의 충돌이 있을 때, 이 부분을 조정하여 결정해야 하는 사항이다.

간단한 사례

간단한 사례로 "학교 프로젝트를 만들기 위한 발표 자료를 어떻게 준비할까?"를 예로 들어 ADR 형식으로 만들어 보자.

 

  손으로 직접 그림 그리기 파워포인트 슬라이드 사용 큰 포스터로 만들기
장점 (만족하는 품질 속성) 창의적이고 독창적임. 
준비 비용이 적음
수정이 쉽고 깔끔함
팀과 쉽게 공유 가능
시각적으로 강렬함
한눈에 보기 좋음
단점 (손해보는 품질 속성) 시간이 오래 걸림
수정이 어려움
컴퓨터가 필요함
디자인에 시간 소요
운반이 불편함
수정이 어려움
큰 공간 필요

 


이해관계자인 팀원들과 수정이 쉽고 깔끔하게 보이고, 팀원들과 쉽게 공유하고 의견을 주고받을 수 있기 때문에 파워포인트 슬라이드 사용하기로 의사 결정하였다. 이렇게 의사 결정 했을 때에는 디자인에 시간이 소요되고 컴퓨터가 필요하다는 것을 알고 있다. 다지안의 경우는 미리 제공되는 템플릿을 최대한 활용하여 시간을 절약하기로 하였고, 디자인 감각이 있는 팀원이 디자인은 전담하기로 역할 분담을 하였다. 발표에도 컴퓨터가 필요하기 때문에 컴퓨터가 필요하다는 것을 확인하였고 팀원 중 한명이 준비하기로 하였다. 

아마도 다른 옵션들을 선택하는 경우도 있을 수 있다. 제약으로 컴퓨터를 사용하지 못할 경우도 있고, 포스터 세션처럼 운용될 수도 있어서 다른 옵션을 선택해야만 하는 경우도 있을 수 있다. 즉, 다른 옵션들도 의미 없이 그냥 만든 것이 아니고 많은 고민을 해야 하는 옵션들인 것이다.

결론

위에서 살펴 본 것과 같이 ADR에 대해서 살펴 보았고, 아주 간단한 사례를 통해서 여러 옵션들을 도출하고 이를 비교해서 의사 결정을 하는 사례도 살펴 보았다. 

참고 문헌

[1] 올라프 짐머만, 미르코 스토커, 다니엘 뤼브케, 우베 즈둔, 세자레 파우타소, "마이크로서비스 API 디자인 패턴, 쉬운 통합을 위한 결합도 최적화 전략" 에이콘출판, 이승범 (옮긴이)  

개요

리엔지니어링 패턴의 10장 다형성 적용한 조건문 변환은 객체 지향 리엔지니어링 패턴 중에서 조건문을 다형성으로 변환하는 데 중점을 둔다. 이러한 변환은 시스템의 유연성과 유지 보수성을 높이는 데 기여하며, 다양한 조건문을 대체할 수 있는 6가지 주요 패턴을 제시한다. 각 패턴은 특정 상황에서 반복적으로 발생하는 문제를 해결하기 위해 설계되었다.

주요 패턴 요약

  1. 자신 타입 체크 변환하기
    • 클래스의 타입을 검사하는 조건문을 각 타입에 맞는 서브클래스와 다형성 메서드 호출로 대체하여 확장성을 개선한다.
  2. 클라이언트 타입 검사 변환하기
    • 클라이언트 클래스에서 특정 프로바이더 타입을 검사하는 조건문을 제거하고, 각 프로바이더에 새로운 메서드를 추가하여 결합도를 줄인다.
  3. 상태 추출하기
    • 상태(State) 디자인 패턴을 적용하여 객체의 상태에 따라 다른 동작을 수행하도록 하며, 상태를 별도의 클래스 객체로 캡슐화하여 유지 보수성을 향상시킨다.
  4. 전략 추출하기
    • 전략(Strategy) 패턴을 적용해 알고리즘을 캡슐화하고, 조건문을 대체하여 다양한 전략을 동적으로 교체할 수 있도록 한다.
  5. 널 객체 도입하기
    • 널 값을 검사하는 조건문을 널 객체로 대체하여 클라이언트 코드의 간소화 및 가독성을 높인다.
  6. 조건문을 등록으로 변환하기
    • 도구와 클라이언트 간의 결합도를 낮추기 위해 조건문을 등록(Registration) 메커니즘으로 대체하여 모듈화와 유연성을 개선한다.

이 패턴들은 조건문을 다형성으로 변환하여 코드 중복을 줄이고, 향후 시스템 확장을 보다 유연하게 할 수 있도록 한다.

 

참고 문헌
[1] Serge Demeyer et al., "Object-oriented Reengineering Patterns"
[2] https://github.com/blcktgr73/OORP

리엔지니어링 패턴의 9장 책임 재배치는 기존 시스템의 클래스와 객체들이 지나치게 많은 책임을 갖거나, 너무 적은 책임만 수행하는 문제를 해결하는 방법론이다. 세 가지 주요 패턴에 대해 이야기 한다.

  1. 동작을 데이터 가까이 이동하기
    데이터 컨테이너에서 행동을 수행하는 클라이언트 클래스에 정의된 행동을 데이터가 있는 곳으로 이동하여 캡슐화를 강화하는 방식이다. 이를 통해 클라이언트가 데이터 구조에 대한 직접적인 의존을 줄이고, 코드 중복을 줄이는 효과가 있다. 이 패턴은 데이터 컨테이너를 더욱 객체답게 만들고, 클라이언트 코드의 유지 보수를 쉽게 한다.
  2. 탐색 코드 제거하기
    객체 간 탐색을 줄여 클래스 간 결합도를 낮추는 패턴이다. 특정 객체의 속성에 접근하기 위해 여러 단계를 거쳐야 할 경우, 탐색 코드를 데이터 컨테이너 내로 옮겨 캡슐화를 높인다. 이를 통해 클래스 간의 불필요한 종속성을 줄이고, 변경의 영향을 최소화할 수 있다.
  3. 신 클래스(God Class) 분할하기
    하나의 클래스에 지나치게 많은 책임이 집중된 경우, 이를 여러 작은 클래스로 분리하는 방법이다. 신 클래스는 여러 기능을 담당하며, 시스템의 모든 제어를 맡아 비대해진 클래스이다. 이를 분할하여 각 기능을 적절한 클래스에 배분함으로써 유지 보수성을 높이고, 객체 지향 설계를 강화할 수 있다.

이 세 패턴은 책임을 올바르게 분배하고, 코드의 응집도와 캡슐화를 개선하는 데 중점을 두고 있다.

 

참고 문헌
[1] Serge Demeyer et al., "Object-oriented Reengineering Patterns"
[2] https://github.com/blcktgr73/OORP

[1]의  9장에서는 API의 계약 문서화와 이해 관계자들과 커뮤니케이션을 위한 패턴을 다룬다.

1. API 설명

  • 설명: API의 기능, 메시지 구조, 동작의 의미 등을 문서화하여 클라이언트 개발자가 이해할 수 있도록 한다. OpenAPI와 같은 기술적 계약 설명 언어를 사용할 수 있다.
  • 주요 특징:
    • 상호 운용성 보장
    • 정보 은닉 유지
    • 확장성과 진화 가능성 지원
  • 포스의 충돌:
    • 지나치게 복잡한 설명은 유지보수에 어려움을 주고, 간단한 설명은 상호 운용성을 해칠 수 있음.
    • 정보 은닉과 상호 운용성 사이의 균형을 유지해야 함.

2. 요금 책정 플랜

  • 설명: API 사용량에 따라 요금을 청구하는 플랜을 정의하는 패턴. 구독 기반 요금제, 사용량 기반 요금제 등이 있으며, 고객의 사용량을 정확히 측정하고 요금 부과.
  • 주요 특징:
    • 경제적 측면, 정확성, 세분성, 보안 등의 고려 필요
    • 구독형, 사용량 기반, 시장 기반 등의 요금제 변형 가능
  • 포스의 충돌:
    • 사용량 측정과 청구의 정확성을 유지하면서, 비용 효율적인 방법을 찾아야 함.
    • 고객의 만족과 프로바이더의 수익성 사이의 균형 유지 필요.

3. 사용 비율 제한

  • 설명: 클라이언트가 API를 과도하게 사용하는 것을 방지하기 위한 패턴. 주기적으로 재설정되는 간격 기반 전송률 제한을 사용하여 과도한 요청을 차단하거나 제한.
  • 주요 특징:
    • 경제적 측면과 성능 보장
    • 남용 방지 및 신뢰성 유지
  • 포스의 충돌:
    • 너무 엄격한 제한은 사용자의 불만을 초래할 수 있으며, 너무 느슨한 제한은 시스템의 안정성을 해칠 수 있음.
    • 서비스 품질과 클라이언트의 자유로운 사용 사이의 갈등을 조율해야 함.

4. 서비스 수준 계약 (SLA)

  • 설명: API가 제공하는 서비스의 품질을 명시적으로 정의한 계약. 특정 서비스 수준 목표(SLO)를 포함하여, 이를 충족하지 못했을 때의 벌칙이나 보상 등을 규정.
  • 주요 특징:
    • 가용성, 성능, 보안, 법적 준수 등의 품질 특성 측정 가능
    • 소비자 관점에서의 매력도 향상
  • 포스의 충돌:
    • 높은 품질 보증은 프로바이더에게 높은 비용과 위험을 수반할 수 있음.
    • 클라이언트의 신뢰를 얻으면서도 비용 효율적인 방법을 찾아야 함.

 

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

[1]의  8장에서는 다룬 API 진화 패턴을 다룬다. 각 패턴에 대한 설명, 주요 특징, 그리고 충돌하는 요구 사항(포스)을 포함한다.

변경 사항 도입 패턴:

  1. 공격적 폐기
    • 설명: 이전 버전을 빠르게 폐기하고, 클라이언트에게 빠르게 신규 버전으로 전환하도록 강제.
    • 주요 특징:
      • 사용 빈도가 낮은 기능을 신속히 제거.
      • 유지 관리 비용 절감.
      • 최신 버전 채택 촉진.
    • 포스:
      • 신속한 혁신과 클라이언트 안정성 간의 균형.
      • 빠른 전환이 어려운 클라이언트와의 충돌 가능성.
  2. 실험적 미리 보기
    • 설명: 초기 버전을 미리 공개하여 클라이언트가 테스트하고 피드백을 제공할 수 있게 함.
    • 주요 특징:
      • 초기 채택과 피드백 장려.
      • 정식 출시 전 API를 개선할 수 있음.
    • 포스:
      • 불안정한 기능 노출의 위험.
      • 기능의 안정성과 클라이언트 기대치 관리 필요.
  3. 2개의 상용 버전
    • 설명: 기존 버전과 새로운 버전을 동시에 유지하여 점진적인 전환 지원.
    • 주요 특징:
      • 클라이언트의 중단 없는 전환 가능.
      • 역호환성 제공.
    • 포스:
      • 여러 버전을 유지 관리하는 데 필요한 자원 증가.
      • 새로운 기능과 이전 버전 지원 간의 균형.
  4. 제한적 수명 보장
    • 설명: API 버전의 지원 기간을 명확히 설정.
    • 주요 특징:
      • 버전 지원 종료 시점을 명확히 하여 클라이언트의 계획 수립 도움.
    • 포스:
      • 클라이언트의 기대치와 실제 지원 기간 간의 조율 필요.
      • 더 긴 지원이 필요한 클라이언트와의 충돌 가능성.
    •  

버전 표시 패턴:

  1. 버전 구분자
    • 설명: 명확한 버전 식별자를 사용하여 API 업데이트 구분.
    • 주요 특징:
      • 역호환성 관리.
      • 클라이언트가 특정 버전을 선택할 수 있게 함.
    • 포스:
      • 버전 관리 규칙의 엄격한 제어 필요.
      • 여러 버전이 동시에 사용될 때의 어려움.
  2. 시멘틱 버전 관리
    • 설명: 구조화된 버전 체계(예: major.minor.patch)를 사용하여 변경의 성격을 표시.
    • 주요 특징:
      • 버전 간 호환성 이해를 간편하게 만듦.
      • 중요한 변경 및 신규 기능을 명확히 신호.
    • 포스:
      • 새로운 기능 추가와 역호환성 유지의 균형 필요.
      • 일관된 버전 규칙 준수가 요구됨.

호환성 보장 패턴:

  1. 서비스 수준 계약(SLA)
    • 설명: API의 가용성, 성능 및 지원에 대한 명확한 기대치를 설정.
    • 주요 특징:
      • 클라이언트에게 안정성을 보장.
      • 신뢰성과 가동 시간 기준 설정.
    • 포스:
      • 안정성을 보장하면서 지속적인 개선을 하는 것의 충돌.
      • 높은 기준을 유지하기 위한 비용 부담.

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

[1]의  7장에서는 주로 메시지 설계 품질을 개선하는 다양한 패턴과 접근 방식을 설명한다. API의 직관적 이해, 성능, 진화 가능성과 같은 품질 요소의 중요성을 설명하며, 성능과 보안, 확장성 등의 상충하는 요구 사항 사이에서 균형을 맞추는 방법을 다룬다. 패턴을 크게 나누면, 케시지 크기 및 요청 수 조정, 참조 관리 그리고 제어 및 표현 정도에 따른 패턴으로 구분할 수 있다. 각 패턴의 설명과 주요 특징, 그리고 패턴 적용 시 발생할 수 있는 주요 요구 사항인 '포스(force)' 충돌에 대해 요약한다.

메시지 크기 및 요청 수 조정하기를 위한 패턴

  1. 요청 번들
    • 설명: 여러 작은 요청을 하나의 큰 요청으로 묶어 클라이언트가 여러 번의 요청을 보내지 않도록 한다.
    • 주요 특징:
      • 네트워크 대역폭 절약
      • 응답 지연 시간 감소
      • 클라이언트 구현 단순화
    • 포스의 충돌:
      • 처리 복잡성 증가 vs. 성능 최적화
      • 클라이언트-서버 간 데이터 일관성 유지 필요
  2. 조건부 요청
    • 설명: 클라이언트가 이미 보유한 데이터와 서버의 데이터를 비교하여 변경된 데이터만 전송받도록 한다.
    • 주요 특징:
      • 네트워크 사용량 감소
      • 서버 및 클라이언트 간 데이터 일관성 유지
    • 포스의 충돌:
      • 효율성 vs. 추가 구현 복잡성
      • 상태 관리 필요성 증가
  3. 페이지네이션
    • 설명: 대량의 데이터를 청크로 나누어 클라이언트가 순차적으로 필요한 데이터만 가져오게 한다.
    • 주요 특징:
      • 대용량 데이터의 효율적 전송
      • 클라이언트의 메모리 사용 최적화
    • 포스의 충돌:
      • 데이터 최신성 vs. 성능 최적화
      • 네트워크 안정성과 리소스 사용 조정 필요

참조 관리의 대안으로서 패턴

  1. 임베디드 엔티티
    • 설명: 필요한 데이터를 응답 메시지에 직접 포함하여 클라이언트가 추가 요청 없이 필요한 모든 데이터를 얻도록 한다.
    • 주요 특징:
      • 관련 데이터의 한 번에 전송
      • 클라이언트-서버 간 추가 요청 최소화
    • 포스의 충돌:
      • 데이터 일관성 vs. 메시지 크기 증가
      • 전송 시간 증가와 대역폭 소비
  2. 링크된 정보 보유자
    • 설명: 관련 데이터를 직접 포함하는 대신, 해당 데이터를 참조하는 링크를 제공하여 필요 시 클라이언트가 추가 요청을 통해 접근할 수 있게 한다.
    • 주요 특징:
      • 메시지 크기 감소
      • 독립적 데이터 관리 가능
    • 포스의 충돌:
      • 효율성 vs. 추가 요청 필요성
      • 데이터의 최신성 유지 vs. 데이터 접근 지연

제어 및 표현의 정도에 따른 패턴

  1. 위시 리스트
    • 설명: 클라이언트가 요청 시 필요한 응답 데이터의 속성만 지정하여 선택적으로 데이터를 요청한다.
    • 주요 특징:
      • 데이터 전송 최적화
      • 클라이언트의 요구에 맞춘 맞춤형 응답 제공
    • 포스의 충돌:
      • 성능 최적화 vs. 클라이언트 복잡성 증가
      • 정확한 데이터 전달 vs. 데이터 취합의 어려움
  2. 위시 템플릿
    • 설명: 클라이언트가 중첩된 데이터 구조에서 필요한 부분만을 요청하여 더 세부적으로 응답을 조정할 수 있다.
    • 주요 특징:
      • 데이터 과다 전송 방지
      • 세밀한 데이터 제어 가능
    • 포스의 충돌:
      • 데이터 간결성 vs. 클라이언트-서버 간 데이터 처리 복잡성
      • 성능 향상 vs. 클라이언트의 정확한 요청 설계 필요

 

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

[1]의 6장은 API 설계와 관련된 내용으로, 특히 요청 및 응답 메시지에 포함되는 메시지 표현의 설계에 대한 다양한 패턴과 고려 사항을 다루고 있다. 클라이언트와 프로바이더 간의 상호 운용성, 성능, 보안, 유지보수성을 보장하기 위해 요청 및 응답 메시지의 표현을 설계하는 것이 중요하다. 또한, 메시지 표현은 데이터 구조의 복잡성과 효율성 간의 균형을 맞추어야 한다. 메시지 표현의 과제는 여러가지가 포함된다. 메시지 크기, 대화의 복잡성, 상호 운용성, 지연 시간, 처리량, 확장성, 유지보수성, 개발자 경험 등 다양한 요소를 고려해야 한다. 그리고, 클라이언트와 프로바이더의 독립적인 배포 가능성을 확보하는 것이 중요하다.

 

패턴 소개

1. 데이터 엘리먼트 (Data Element)

설명:
데이터 엘리먼트는 API 요청 및 응답 메시지에서 도메인 모델 개념을 표현하는 기본 구성 요소이다. 클라이언트와 프로

바이더 간의 통신을 위한 핵심 데이터 구조로 사용된다. 구조화된 데이터로서, 아토믹 파라미터, 파라미터 트리 등 다양한 형태로 존재할 수 있다.

 

주요 특징:

  • 도메인 모델의 복잡한 개념을 추상화하고 구조화하여 데이터 표현을 용이하게 함.
  • 클라이언트와 프로바이더 간의 느슨한 결합(loose coupling)을 촉진해 유지보수성 향상.
  • 데이터 계약(data contract)을 통해 클라이언트가 데이터 구조를 이해하고 상호작용할 수 있게 함.

포스 충돌:

  • 풍부한 기능 vs. 성능: 복잡한 도메인 모델을 노출할수록 클라이언트에게 더 많은 기능을 제공할 수 있지만, 그만큼 성능 저하와 유지보수의 어려움이 있을 수 있다.
  • 보안 vs. 구성의 용이성: 데이터를 많이 노출할수록 보안 위협에 노출될 가능성이 크며, 이에 따라 구성 및 처리 부담이 커질 수 있다.
  • 유연성 vs. 유지보수성: 다양한 표현을 제공하여 유연성을 높이려다 보면 유지보수의 어려움이 생길 수 있다.

 

2. 메타데이터 엘리먼트 (Metadata Element)

설명:
메타데이터 엘리먼트는 요청 및 응답 메시지의 데이터를 설명하거나 보충하는 추가 정보를 제공한다. 이는 메시지의 의미를 명확히 하거나 처리 효율성을 높이는 데 사용된다.

제어 메타데이터, 애그리게이티드 메타데이터, 출처 메타데이터 등 다양한 변형이 있다.

 

주요 특징:

  • 데이터의 의미, 출처, 상태 등의 추가 정보 제공으로 상호 운용성(interoperability)을 강화.
  • 메시지 수신자가 데이터를 더 잘 해석할 수 있도록 도움을 줌.
  • 클라이언트가 데이터 처리와 분석을 효율적으로 할 수 있도록 정보 제공.

 

  • 포스 충돌:
    상호 운용성 vs. 결합도: 메타데이터가 많아질수록 해석이 쉬워져 상호 운용성이 향상되지만, 클라이언트와 서버 간의 결합도가 높아질 수 있다.
  • 사용 편의성 vs. 성능: 메타데이터가 메시지 크기를 늘려 처리 성능을 저하시킬 수 있다.
  • 보안 vs. 관리 용이성: 메타데이터에 보안 정보가 포함될 때, 관리의 복잡성이 증가할 수 있다.

 

3. ID 엘리먼트 (ID Element)

설명:

  • ID 엘리먼트는 API의 엔드포인트, 동작, 메시지 표현을 고유하게 식별하기 위한 데이터 요소이다. 클라이언트가 특정 데이터를 정확히 요청하고 처리할 수 있도록 한다.
  • UUID, URI, URN 등 다양한 형태로 제공될 수 있으며, 글로벌 고유성과 로컬 고유성을 보장할 수 있다.

주요 특징:

  • 각 데이터 요소를 고유하게 식별하여 명확한 참조를 가능하게 함.
  • 글로벌 고유성(예: UUID)과 로컬 고유성(예: 특정 세션 내에서만 유효한 ID)으로 나뉨.
  • 분산 시스템에서도 안정적인 데이터 참조가 가능.

 

포스 충돌:

  • 노력 vs. 안정성: 로컬 ID는 생성이 쉽지만, 글로벌 고유성을 보장하기 어려울 수 있습니다. 반면, 글로벌 ID는 관리가 복잡하지만 안정적이다.
  • 가독성 vs. 보안: 사람이 읽기 쉬운 ID는 보안에 취약할 수 있으며, 무작위화된 ID는 보안은 좋지만 가독성이 떨어질 수 있다.
  • 구조화 vs. 간결성: 데이터베이스 키와 같은 구조화된 ID는 효율적이지만, 관리의 복잡성을 초래할 수 있다.

 

4. 링크 엘리먼트 (Link Element)

설명:

링크 엘리먼트는 메시지 내에서 데이터 요소 간의 관계를 명확히 하여, 클라이언트가 필요한 데이터를 찾고 추가 요청을 수행할 수 있게 합니다. 하이퍼미디어 컨트롤의 일환으로 사용된다. REST API에서 중요한 하이퍼미디어 제어 요소로, 다음 작업 단계나 관련 데이터 리소스를 탐색할 수 있게 한다.

 

주요 특징:

  • 데이터 요소 간의 명확한 관계를 정의하고, 클라이언트가 추가 요청을 수행할 수 있게 함.
  • 하이퍼미디어 패턴을 통해 클라이언트가 더 적은 정보로도 효율적으로 작업을 수행할 수 있게 함.
  • URI, URL 등을 사용해 명확한 데이터 참조를 제공.

 

포스 충돌:

  • 유연성 vs. 복잡성: 클라이언트가 다양한 경로를 탐색할 수 있게 하면 유연성이 높아지지만, 그만큼 메시지의 복잡성도 증가한다.
  • 명확성 vs. 성능: 링크를 사용하면 명확하게 데이터 간 관계를 표현할 수 있지만, 많은 링크는 페이로드 크기를 키워 성능 저하를 초래할 수 있다.
  • 보안 vs. 접근성: 링크를 통해 제공하는 데이터는 보안이 중요하지만, 쉽게 접근할 수 있게 하려다 보면 보안 취약점이 발생할 수 있다.

참고 문헌
[1]  올라프 짐머만 , 미르코 스토커 , 다니엘 뤼브케 , 우베 즈둔 , 세자레 파우타소 , "마이크로서비스 API 디자인 패턴: 쉬운 통합을 위한 결합도 최적화 전략" 에이콘. 이승범 역

여러 다른 글에서도 썼지만, 소프트웨어 아키텍처 설계에서 품질 속성(Quality Attribute)은 중요하게 간주되며 시스템의 성공과 연결된다고 이야기 된다. 그러나 이러한 품질 요구사항을 효과적으로 도출하는 것은 쉽지 않다. 이를 위해 품질 속성 워크숍을 진행한다. 하지만, 이 과정은 최소로 해도 하루에서 2주 가까이 소요되는 큰 작업이다.  이러한 것을 조금 더 작게 할 수 있는 '미니 품질 속성 워크숍(Mini Quality Attribute Workshop, Mini QAW, 미니 QAW)'이 유용한 도구로 활용될 수 있다.

미니 QAW 개요

미니 QAW는 전통적인 품질 속성 워크숍(Quality Attribute Workshop, QAW)의 간소화된 버전으로, 짧은 시간 내에 효율적으로 품질 요구사항을 도출하기 위해 고안되었다. 특히 애자일(Agile) 팀이나 경험이 적은 퍼실리테이터에게 적합하며, 몇 시간에서 반나절 정도의 시간으로 진행할 수 있다[1].


목적

미니 QAW의 주요 목적은 다음과 같다.
- 품질 요구사항 도출: 시스템의 주요 품질 속성을 이해하고, 이를 기반으로 아키텍처 설계에 반영합니다.
- 이해관계자 참여 촉진: 다양한 이해관계자의 의견을 수렴하여 시스템의 품질 목표를 명확히 합니다.
-효율적인 시간 활용: 짧은 시간 내에 핵심 품질 요구사항을 도출하여 프로젝트 진행 속도를 높입니다.

워크숍 구성 요소

미니 QAW를 성공적으로 진행하기 위해서는 다음과 같은 요소가 필요하다.

- 이해관계자: 시스템의 주요 사용자, 개발자, 관리자 등 다양한 관점을 제공할 수 있는 참여자들
- 퍼실리테이터: 워크숍을 이끌고 논의를 조율하는 역할을 담당하는 진행자
- 품질 속성 분류표: 성능, 보안, 가용성 등 다양한 품질 속성을 정리한 자료
- 시나리오 작성 도구: 시나리오를 작성하고 공유할 수 있는 도구나 템플릿

진행 방법

미니 QAW는 다음과 같은 단계로 진행된다.
1. 소개 및 품질 속성 이해: 퍼실리테이터가 워크숍의 목적과 품질 속성 분류표를 소개한다.
2. 이해관계자 공감 지도 작성: 참여자들이 부재 중인 이해관계자의 관점에서 품질 요구사항을 추정하여 작성한다.
3. 시나리오 브레인스토밍: 참여자들이 시스템의 품질 속성과 관련된 다양한 시나리오를 제시한다.
4. 시나리오 우선순위 결정: 제시된 시나리오에 대해 투표를 통해 우선순위를 정한다.
5. 시나리오 정제: 우선순위가 높은 시나리오를 구체화하고 상세하게 작성한다.

간단 사례

예를 들어, 온라인 도서 판매 시스템을 개발한다고 가정해보자. 이해관계자 공감 지도 작성 단계에서, 참여자들은 고객 서비스 담당자의 관점에서 "시스템이 24시간 안정적으로 운영되어야 한다"는 요구사항을 도출할 수 있다. 이러한 요구사항은 이후 시나리오 브레인스토밍과 정제 과정을 통해 구체화된다.


1. 소개 및 품질 속성 이해

퍼실리테이터는 워크숍의 목표를 소개하고, 품질 속성 분류표(예: 성능, 가용성, 보안 등)를 설명한다.

  • "이 워크숍은 온라인 도서 판매 시스템의 품질 목표를 정의하고, 우선순위가 높은 품질 속성을 도출하는 것이 목적입니다."
  • "품질 속성 예로는 페이지 로드 시간(성능), 시스템의 24시간 무중단 운영(가용성), 그리고 결제 정보 보호(보안)가 있습니다."

 

2. 이해관계자 공감 지도 작성

참여자들은 시스템과 관련된 이해관계자를 식별하고, 그들의 관점에서 품질 요구사항을 도출한다.

  • 이해관계자 식별: 고객, IT 운영팀, 서드파티 결제 제공자 등.
  • 예시: 고객 서비스 담당자 역할을 맡은 참여자는 다음과 같은 요구사항을 도출한다.
    • "고객은 사이트가 항상 사용 가능하길 원한다." → 가용성
    • "결제 실패 없이 빠르게 완료되길 바란다." → 성능 및 신뢰성
    • "고객 정보가 안전하게 보호되어야 한다." → 보안

 

3. 시나리오 브레인스토밍

참여자들은 각 품질 속성에 대한 구체적인 시나리오를 제안한다.

예시 시나리오:

  •    가용성: "시스템이 예상치 못한 서버 다운타임 발생 시, 1분 이내에 복구되어야 한다."
  •    성능: "사용자가 도서 검색을 실행할 때 결과는 2초 이내에 표시되어야 한다."
  •    보안: "사용자의 결제 정보는 암호화된 채널로만 전송되어야 한다."

 

4. 시나리오 우선순위 결정

참여자들이 제안된 시나리오 중 가장 중요한 항목에 투표한다.

우선순위 예시:

   1. "결제 정보 보호(보안)" → 온라인 결제 시스템의 핵심.

   2. "2초 이내의 검색 응답(성능)" → 고객 만족도에 큰 영향.

   3. "1분 이내 서버 복구(가용성)" → 사업 지속성에 필수.

5. 시나리오 정제

우선순위가 높은 시나리오를 구체화하여 시스템 요구사항으로 전환한다.

결제 정보 보호 시나리오:

  • 시나리오: 사용자가 도서를 결제할 때, 모든 결제 정보는 HTTPS 프로토콜을 사용해 암호화되어 전송된다.
  • 요구사항: 모든 결제 트랜잭션은 PCI DSS 표준을 준수해야 한다.

검색 성능 시나리오:

  • 시나리오: 사용자가 도서 제목을 입력하고 검색 버튼을 누르면 2초 이내에 검색 결과가 반환된다.
  • 요구사항: 데이터베이스 쿼리 성능 최적화와 캐싱 시스템을 도입한다.

결과물

미니 QAW를 통해 다음과 같은 결과물을 얻을 수 있다.

  • 우선순위가 매겨진 품질 속성 시나리오 목록: 시스템 설계 시 고려해야 할 주요 품질 요구사항
  • 이해관계자들의 품질 속성에 대한 공통된 이해: 팀 내에서 품질 목표에 대한 일치된 인식
  • 아키텍처 설계의 방향성 확보: 도출된 품질 요구사항을 기반으로 한 아키텍처 설계 지침

마무리

미니 QAW는 짧은 시간 내에 효율적으로 품질 요구사항을 도출하고, 이해관계자들의 참여를 촉진하는 유용한 워크숍이다. 이를 통해 시스템의 품질 목표를 명확히 하고, 아키텍처 설계의 방향성을 확보할 수 있다.

미니 QAW에 대해 더 자세히 알고 싶다면, [1], [2] 를 참고하도록 하자. 이러한 자료를 통해 미니 QAW의 구체적인 진행 방법과 실제 사례를 더욱 깊이 이해할 수 있을 것이다.

참고 문서

[1] Discover Quality Requirements with the Mini-QAW, https://re-magazine.ireb.org/articles/discover-quality-requirements-with-the-mini-qaw
[2] SATURN 2016 Talk: Discover Quality Requirements with the Mini QAW, https://www.youtube.com/watch?v=YGeqqYrCHHg

최근에 Facebook에서 Netflix Architecture[1]라는 포스팅을 본 적이 있다.  이미 댓글에서도 언급했지만, 실재로는 기술 스택(Tehcnology Stack)을 표현한 것이었고 아키텍처 혹은 시스템 아키텍처라고 보기는 어려웠다. 이 두 용어는  자주 사용되지만, 이 두 용어는 서로 다른 개념을 지칭한다. 아마도 이 둘을 혼동하는 이유는 밀접하게 연관되어 있기 때문일 것이다. 

Technology Stack (기술 스택)

기술 스택은 특정 소프트웨어 프로젝트 또는 애플리케이션을 구축할 때 사용되는 기술들의 집합을 의미한다. 이는 프로그래밍 언어, 프레임워크, 데이터베이스, 서버 환경, API 등을 포함할 수 있다. 기술 스택은 주로 개발에 사용되는 도구와 기술들의 "목록"으로 볼 수 있다. 종종 기성 상용품(Commercial Off The Shelf, COTS)인 경우도 많다.

예를 들어, 웹 애플리케이션을 개발하기 위해 다음과 같은 기술 스택을 사용할 수 있습니다:

  • 프론트엔드: React, Angular
  • 백엔드: Node.js, Ruby on Rails
  • 데이터베이스: PostgreSQL, MongoDB
  • 서버 환경: AWS, Azure

System Architecture (시스템 아키텍처)

시스템 아키텍처는 소프트웨어 시스템의 구조적 설계를 말한다. 일반적으로는 구조를 설명하기 위해 시스템의 컴포넌트와 그들이 서로 상호 작용하는 방식을 설명하는 것을 가리킨다. 이러한 설명은 시스템의 요구 사항을 어떻게 만족하는지를 보여 주기 위한 것이 하나의 용처이다. 

예를 들어, 시스템 아키텍처 설계에는 기술 스택 뿐 아니라, 앞에서 이야기 한 것 처럼 시스템의 요구 사항을 어떻게 만족하는지 보여 주기 위한 고려사항이 포함될 수 있다.

- 구성 요소의 배치: 서비스 지향 아키텍처(SOA), 마이크로서비스
- 데이터 흐름: 동기식 API 호출, 비동기식 메시징 시스템
- 보안 구조: 인증 및 권한 부여 방식

결론

기술 스택은 "무엇을" 사용할지에 대한 결정인 반면, 시스템 아키텍처는 "어떻게" 시스템을 구성하여 요구 사항을 만족하는지에 대한 계획이나 설명이다.  개발자와 설계자가 이 두 개념을 혼동하는 것은, 두 분야가 각각 다루는 세부사항과 전반적인 설계가 서로 긴밀히 연결되어 있기 때문일 수 있다. 아키텍처 설명하는데 기술 스택이 사용될 수 있고, 기술 스택이 아키텍처에서 설명하는 것이 부족할 수 있다는 것을 이해한다면 복잡하고 어려운 개발 업무를 효과적으로 진행할 수 있는 기반이 된다.

참고 문서

[1] Netflix Architecture, https://www.facebook.com/tipsbykavindu/photos/netflix-architecture-/536074732617368/?_rdr

+ Recent posts