포스트

2022-02-03-TIL

Today I Learned

VO vs DTO

VO(Value Object)와 DTO(Data Transfer Object)는 둘 다 값을 담는 작은 객체라서 자주 섞어 부르지만, 만들어진 목적이 다르다.

마틴 파울러의 Value Object 글은 객체를 두 부류로 나눈다. 메모리 참조(identity)로 같은지를 판단하는 참조 객체와, 담고 있는 값으로 같은지를 판단하는 값 객체다. 금액이나 날짜 범위처럼 값이 같으면 같은 것으로 취급해야 하는 개념이 값 객체이고, 그래서 equals를 값 기준으로 구현하고 불변(immutable)으로 만드는 것이 자연스럽다. 값이 바뀌어야 하면 기존 객체를 고치지 않고 새 객체를 만든다.

Data Transfer Object는 원격 호출 비용 때문에 나온 패턴이다. 원격 인터페이스는 호출 한 번이 비싸므로, 여러 번 나눠 부르지 않고 필요한 데이터를 한 객체에 모아 한 번에 보낸다. 즉 DTO는 계층이나 프로세스 사이에서 데이터를 옮기는 그릇이고, 도메인 규칙이나 값 기반 동등성은 관심사가 아니다.

구분VODTO
목적도메인 개념을 값으로 표현계층, 프로세스 사이 데이터 전달
동등성값이 같으면 같다보통 신경 쓰지 않는다
가변성불변으로 만든다직렬화 편의상 setter를 두기도 한다
로직값과 관련된 검증, 연산을 가진다로직 없이 데이터만 담는다
  • https://ijbgo.tistory.com/9
  • https://martinfowler.com/bliki/ValueObject.html

방어 로직

방어 로직은 백엔드에서 정합성을 검증하거나, 프론트엔드로부터 들어오는 요청을 막는 방향으로 둘 수 있다. 범위는 CSRF나 XSS 같은 공격 방어까지 포함한다.

  • CSRF(Cross-Site Request Forgery)는 사용자가 로그인한 상태를 악용해, 다른 사이트에서 사용자의 브라우저가 의도하지 않은 요청을 보내게 만드는 공격이다. OWASP 치트시트는 서버가 발급한 토큰을 요청에 함께 싣게 하는 동기화 토큰 패턴(Synchronizer Token Pattern) 같은 토큰 기반 방어를 소개한다.
  • XSS(Cross-Site Scripting)는 공격자가 넣은 스크립트가 다른 사용자의 브라우저에서 실행되는 공격이다. OWASP 치트시트는 출력 위치(HTML 본문, 속성 등)에 맞춘 출력 인코딩을 기본 방어로 든다.

프론트엔드 검증은 사용자 경험을 위한 것이고 우회할 수 있으므로, 정합성 검증은 백엔드에도 있어야 한다.


추후에 발생할 수 있는 로직

사례를 흐름대로 적어 둔다.

  1. 지분율 이슈가 생기면 정산에 이슈가 발생하고, 이용권 정산 팀에서 문의가 온다.
  2. 우리 쪽에는 지분율 담당자가 없어서 리바이가 맡게 됐다.
  3. 아무리 봐도 백엔드 문제가 아니었고, 프론트엔드 문제였다.

메시지 브로커

메시지 브로커는 메시지를 보내는 쪽(producer)과 받는 쪽(consumer) 사이에서 메시지를 받아 두었다가 전달하는 중간 시스템이다. 보내는 쪽은 받는 쪽이 지금 살아 있는지 몰라도 되고, 받는 쪽은 자기 속도대로 처리할 수 있다.

  • RabbitMQ: AMQP 0-9-1 모델에서 메시지는 exchange로 발행되고, exchange가 binding 규칙에 따라 queue로 라우팅한다(AMQP 0-9-1 Model Explained).
  • Kafka: 이벤트를 topic에 기록하고, topic은 여러 브로커에 나뉜 파티션으로 저장된다. producer와 consumer는 서로를 전혀 모른 채 분리되어 있다(Apache Kafka Introduction).

Meta API(RabbitMQ)는 종착역 역할을 한다. 우리 팀에서 입수, TC, CMS 등록 과정이 완료되면 메시지 큐로 메시지를 보낸다. Meta API는 그 큐를 바라보고 있다가 들어온 메시지에 대해 정합성 검사와 음원 확인 등을 하고 FLO 쪽으로 다시 큐를 보낸다. 이 부분이 RabbitMQ에서 Kafka로 전환된다.

Spring Cloud Stream은 메시지 브로커를 사용하지만 특정 브로커에 묶이지 않고 다른 브로커로 대체할 수 있다. 공식 문서에 따르면 Spring Cloud Stream은 외부 미들웨어의 실제 목적지(destination)에 연결하는 Binder 추상화를 제공하고, Kafka, RabbitMQ 같은 브로커별 구현은 바인더로 갈아 끼운다. 애플리케이션 코드는 바인딩 이름만 알고 있으므로, 브로커를 바꿀 때 코드보다 의존성과 설정을 바꾸는 쪽에 가깝다.

현재는 2천만 번까지는 괜찮다는 임계치만 공부해서 적용한 상황이다.

참고한 자료외부 출처 7

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다