나의 개발 일상 기록
[MSA] 주문 프로젝트_Partner Domain2 본문
응용 계층, 외부 인터페이스 계층 구현(Application, Interfaces package)
Facade 구현(Application)
Facade 패턴의 정의는 다양한 외부 인터페이스를 하나의 인터페이스로 통합하는 개념이라고 말할 수 있습니다. 다시 말해 복잡한 시스템 뒤단은 숨기고 간단한 인터페이스를 제공하는 객체라고 할수 있습니다.
여기에서는 비즈니스 결정을 내지진 않지만 수행할 작업을 정의하여 Transaction으로 묶여야 하는 도메인 로직과 그 외 로직을 Aggregation하는 역할로 한정 짓습니다. 로직의 조합이라는 측면을 관점으로 Facade를 차용합니다.
1. 응용 계층에서 구현해야할 Partner 도메인의 요구사항을 구현합니다.
비즈니스 규칙은 포함하지 않으며, 작업을 조정하고, 다음 하위 계층에서 도메인 객체의 협력을 위해 업무를 위임을 하는 역할는 하는 Facade는 Partner 도메인의 요구사항을 구현하여야 합니다. 예를 들어 파트너의 등록 시 파트너의 정보를 저장하는 Transaction과 정보 저장 완료 후 등록이 완료되었다는 메일 발송을 하는 Aggregation가 있다고 가정을 한다면 Facade에서는 저장관련 Service에 저장을 요청을 할 것이고 저장이 완료 시 메일 발송 관련 Service에 메일 발송 요청을 할 것입니다. 두개의 요구사항을 따로 분리하는 이유는 메일 발송에 실패를 하더라도 파트너 등록이 정상적으로 이루어졌다면 큰 문제가 되는 상황이 아니기 때문입니다.
<예시>
public class PartnerFacade {
public PartnerInfo registerPartner(Request request){
// 파트너 정보 등록
// 등록 된 파트너에게 메일 발송
// 결과 리턴
}
}
Controller 구현(Interface)
Controller는 외부 인터페이스 구현 기술에 관계없이 도메인 계층 로직을 호출하고 이에 대한 결과를 변환하여 응답으로 제공합니다. HTTP API, gPRC, 비동기 메시징 등의 다양한 통신 방법을 사용할 수 있어야 합니다. 외부 인터페이스 계층 구현은 서비스 전체의 시스템간 인터페이스 표준을 정의하고 그에 맞게 외부 호출과 응답이 정의되도록 구현 되어야 합니다. 또한, 시스템 간의 일관된 응답체계를 위한 공통 응답과 변환 로직을 구현하는 것도 좋습니다.
1. layer간 별도의 dto를 정의합니다.
외부 서비스의 요청과 응답은 내부 도메인 로직을 처리하는 layer와 명확히 분리되어야 합니다. 이를 위해 interface layer에서 사용할 dto를 정의하고 해당 dto가 domain layer로 침투되지 않도록 유의해야 합니다. 이처럼 별도 layer간 dto를 정의하는 이유는 UI화면마다 사용하는Model의 정보는 상이하지만, Model 객체는 UI에서 사용하지 않을 불필요한 데이터까지 보유하고 있으며 비즈니스 로직 등 User의 민감한 정보가 외부에 노출되는 보안 문제와도 직결되기 때문입니다. 또한, UI계층에서 Model의 메서드를 호출하거나 상태를 변경시킬 위험이 존재하기에 dto를 별도로 정의하는 것이 좋습니다.
2. Facade를 호출하고 결과를 받아 API 응답에 맞게 변환합니다.
API응답 체계를 http status code를 사용하거나 자사 시스템에만의 응답 체계를 구축하여 사용하는 경우가 있습니다. API응답 체계는 어떤 형태이든지 시스템 전체 API의 응답이 명시적이고 일관된 것이 중요합니다. 요청이 어디에서 오는지와 무관하게, 동일한 리소스에 대한 모든 API요청은 동일하게 보여야 합니다.
<예시>
/**
API endpoint 는 /api/{version}/{도메인명} 의 패턴을 prefix 로 한다.
content-type 은 application/json 으로 한다.
**/
// 성공 응답
{
"result": "SUCCESS",
"data": "plain text 또는 json 형태의 데이터",
"messsage": "성공 메시지",
"error_code": null
}
// 실패응답
{
"result": "FAIL",
"data": null 또는 json 형태의 데이터
"messsage": "에러 메시지",
"errorCode": "plain text"
}
* 로깅의 중요성
로깅(logging)은 정보를 제공하는 일련의 기록인 로그(log)를 생성하도록 시스템을 작성하는 활동을 말한다.
이런 로그들은 테스트할 때 재현하기 힘든 버그가 개발 완료된 환경에서 발생했을 경우, 그런 버그들에 대한 정보를 알려줄 수 있으며, 구문들 사이에 걸리는 시간 등의 성능에 관한 통계와 정보를 제공할 수 있다. 로그가 제공하는 정보의 양은 프로그램이 실행되는 중에도 설정이 가능한 것이 이상적이다. 초보자들은 프로그래밍에 대해 아는 것에 한계가 있기 때문에 로그를 사용해야 하고, 시스템 설계자들은 시스템의 복잡성 때문에 로그를 이해하고 사용해야 한다.
특히 API레벨의 request, response 로깅은 추후 리펙토링에 필수 항목이 될 수 있습니다. 테스트 코드가 적절히 작성되지 않은 시스템 환경에서는 API의 request, response 로그만이 시스템 개선을 가능하게 해주며 문서화된 스펙보다 정확한 것은 API의 request, response 로그입니다. 로깅 및 애플리케이션 모니터링 서비스는 어떤 것을 사용하든지 시스템 전체를 파악하기 위한 로깅과 모니터링 수단은 갖추어야 합니다. 그래야만 서비스르 이용하는 유저가 에러를 접하게 되면 개발팀은 이를 즉시 인지할 수 있어야 합니다. 또한 이를 기반으로 빠르게 에러 상황에 대응할 수 있어야 합니다.
로그의 라이브러리 종류
- java.util.loggin
JDK 1.4부터 포함된 표준 로깅 API입니다. 별도의 라이브러리를 추가할 필요가 없습니다. 하지만 기능이 많이 부족하여 다른 로그 라이브러리를 더 많이 사용합니다.
- Apach commons logging
아파지 재단의 commons 라이브러리 중 로그 출력을 제공하는 라이브러리입니다.
- Log4j
아파지 재단에서 제공하며, 가장 많이 사용되는 라이브러리입니다.
- Logback
Log4j의 단점을 개선하고 기능을 추가하여 개발한 로깅 라이브러리입니다.
- SLF4J
SLF4J는 이러한 라이브러리들을 하나의 통일된 방식으로 사용할 수 있는 방법을 제공하고 있습니다. SLF4J는 로깅 Facade(퍼사드)입니다. 로깅에 대한 추상 레이어를 제공하는 interface의 모음입니다.
'MSA > MSA 구축' 카테고리의 다른 글
| [MSA] 선물하기 프로젝트_Flow설계 및 검토 (0) | 2021.09.17 |
|---|---|
| [MSA] 주문 프로젝트_OrderDomain (0) | 2021.09.16 |
| [MSA] 주문 프로젝트_ItemDomain (0) | 2021.09.14 |
| [MSA] 주문 프로젝트_Partner Domain1 (0) | 2021.09.09 |
| [MSA] MSA 프로젝트 구조 및 설계 (0) | 2021.09.08 |