⌛ Ady 프로젝트 회고 -3- ⌛

Now.Me·2022년 11월 11일
0

past-me

목록 보기
3/3
post-thumbnail

💎 지난 이야기...

2022년 1월, 신입인 나와 주니어 백엔드 개발자 둘이서 광고 판매 플랫폼 프로젝트인 Ady를 시작하게 되었어. Ady는 자사의 도메인을 모두 담을 수 있으면서 이후에 확장성까지 고려해야했어. 그래서 여러 복잡한 데이터를 유연하게 담을 수 있어야했고 여러 예외 상황도 담을 수 있어야했어.

도메인 지식을 습득하고 UI/UX를 설계,디자인 하고 이제 PoC까지 끝냈지. 이제는 신나게 개발만 하면 되는거였어. PoC를 해봤고 꽤 복잡한 프로세스 하나가 한달 반만에 개발이 끝났어. 그래서 앞으로 남은 6단계도 금방 걸릴꺼라 생각했어. 심지어 그중 4개의 프로세스는 거의 비슷했으니 앞으로 5개월이면 알파버전 정도는 나올꺼라 생각했어. 9월까지는 개발이 끝날것이라 예상했어.

하지만 이건 나의 착각이었던거지... 원래 무식하면 용감하다고 나는 겨우 개발 경력 1개월인 나를 너무 과대평가했었던거지.

💎 백엔드 데이터 설계, 실수와 발전

저번에 말했듯, Ady에는 주니어 백엔드 개발자 1명과 신입 프론트개발자인 나 이렇게 두명만 개발에 참여했어. 그래서 초반에 열심히 도메인을 공부했던 내가 백엔드의 기초 지식부터 배워나가며 백엔드 개발자님과 같이 데이터 설계에 참여했지.

우리가 담으려는 도메인은 모든게 확실히 정의 된것도 없고 그렇다고 정리가 되어있지 않았어. 말 그대로 고객이 까라면 까야되는 그런 상황인거지. 게다가 이후에 우리 회사 외에도 이 시스템을 사용할 수 있어야했어. 그럴려면 현재 도메인을 모두 담으면서 유연하게 변경이 가능할 수 있어야했어. 각 기업이 가지고 있는 판매 룰들을 기업단위로 공유하는 동시에 매체에 송출이 될 때는 기업간의 송출 단위가 통일되어야 했어.

가장 복잡했던 것은 기업관의 관계였어. 각 기업별로 하나의 동일한 매체에 대해 가지고 있는 권한이 다 다른거야. 하청의 하청까지 담을 수 있는 그런 말도 안되게 복잡한 도메인이었던거지.

🎯 데이터 중심 설계

처음에는 Ady를 데이터 중심 설계로 간단하게 ERD를 그리며 간단하게 구현하게 되었어. 완성된 ERD를 팀원들과 공유하고 피드백을 받았는데 딱히 고치라는 피드백은 없었어. 그래서 완벽하다며 자만했다.(부끄럽다ㅜㅜ)

하지만 개발단계로 넘어가니 비효율적인 부분이 보였고 처음 설계했던 의도를 정확히 파악하기 어려웠어. 뭐랄까... 주어 목적어만 열심히 적어놓고 그 사이에 동사가 빠진 것 같은 느낌? 이 객체와 저 객체가 연관이 있는 건 알겠는데 어떻게 연관이 있는지 전혀 모르겠었지.

🎯 객체 지향 프로그래밍

그렇게 문제를 인지하고 얼마안가 백엔드 개발자님께서 객체 지향 프로그래밍에 대한 지식을 배워서 나에게 공유해주셨어. 이제는 그저 관련있는 데이터를 데이터베이스에 때려 박는 것에 급급한게 아니라 객체와 객체가 어떻게 상호작용하는지에 대해 정의하기 시작했지. 더 나아가 도메인에 따라 객체 지향 설계를 하여 도메인을 녹아낼 수 있는 설계로 진화해갔어. 그제서야 백엔드에 기능을 수정하고 삭제하고 추가하는게 점점 용이해져갔어. 하지만 저번달까지도 조금씩의 변경이 있었어. 도메인도 계속 변했고 사람마다 도메인에 대한 설명이 다르더라고ㅜㅜ

내가 설계를 도울 때 잘 쓰던 팁이 있어. 정의한 객체로 역할극을 해보는 거야. 개발자 관점에서 추상적으로만 생각하면 길을 잃기 쉽더라고. 그냥 객체를 하나의 물건 또는 사람이라 생각하고 이걸 도메인 내에서 직접 시뮬레이션을 돌려보는거지. 그럼 생각하지 못한 여러 예외를 발견하고 다른 방법으로 설계할 수 있더라.

🎯 CQRS

CQRS(Command and Query Responsibility Segregation)는 백엔드에서 Command와 Query부분으로 나누어 데이터를 관리하는 거야. Command 모델은 프론트엔드에서 받아온 데이터 덩어리를 열심히 잘 나눠놓은 객체에 맞게 데이터를 찢어 저장하는거야. 하지만 Query는 또 달라. 예를 들어서 내가 물건이라는 객체와 상품이라는 객체로 나누어놨어. 상품은 물건 리스트와 상품 가격을 가지고 있지. 그래서 데이터베이스 상에는 상품이 물건의 id 리스트와 price를 가지고 있어. 하지만 물건의 id 외에 이름이나 카테고리 등의 자세한 데이터는 상품 테이블만 보고는 찾을 수 없는거야. 그래서 상품에 있는 물건의 id로 물건 데이터를 찾아와야 하는거야. 이렇게 Command 부분과 Qeury 부분은 같은 데이터에 대해 하는 일이 전혀 달라. 그래서 Command와 Query로 모델을 나누어 책임을 분리하는거지.

🎯 BFF

BFF(Backend for Frontend)란 데이터를 프론트엔드 서버로 가져와 이를 프론트엔드에서 원하는 방식으로 만들어 프론트엔드에 전달 해주는거지. 이 개념은 같은 데이터에 대해 화면 크기나 종류에 따라 원하는 데이터가 조금씩 다르기 때문이야. 예를 들어서 모바일 폰의 화면은 데스크탑 화면보다 훨씬 작으니 작은 화면에 맞춘 UI가 필요한데 이 때 모바일 화면에 보여지는 데이터가 데스크탑 화면에 보여지는 데이터보다 적을 수 있어. 그럼 무리하게 필요도 없는 데이터를 모바일폰 화면에 던져줄 필요가 없는거지. 그래서 BFF에서 같은 데이터를 다르게 조합해 적절하게 프론트엔드 화면에 맞춰서 보내주는거야. 백엔드 그 자체가 학교의 주방인거고 BFF가 배급, 그리고 급식을 받는 학생들이 모바일 폰, 태블릿, 데스크탑 등의 클라이언트라고 생각하면 쉬울 것 같아. 급식 주방(백엔드)에서는 일단 필요한 급식(데이터)을 모두 배식(BFF)하는 곳에 던져주고 배식하는 영양사분들이 학생(클라이언트)로 급식(데이터)을 적절하게 배분해주는 것 같은 느낌인 것으로 난 이해했어.

나는 CQRS와 BFF를 배우고 한가지 생각이 떠올랐어. Query 모델을 BFF로 가져올 수 없을까? 어차피 BFF에서 백엔드의 데이터를 받아 프론트엔드에 맞춰서 보내준다고 한다면 Query랑 많이 다를까?하는 물음이었어.

솔직히 처음에 백엔드 개발자님과 개발할 때 좀 비효율적이라고 느꼈던 부분이 있었어. 바로 데이터를 쿼리해 올 때 였지. 나는 프론트엔드 개발자이다 보니까 백엔드에서 데이터를 주지 않으면 받아올 수 없어. 그래서 데이터의 api 스펙이 바뀔때마다 백엔드 개발자님께 부탁을 해서 데이터를 받아와야 했지. 나는 흐름 끊기는 걸 싫어하는 입장에서 각 객체마다 데이터를 받을 수 있는 api를 생성하고 그냥 내가 필요할 때마다 각 객체에서 데이터를 불러와서 필요에 따라 합쳐서 프론트엔드로 보내고 싶다라는 생각을 했어.

예를 들면 이런거야. 게임 유저(프론트엔드 개발자)가 게임의 캐릭터(쿼리 데이터)를 생성하는데 게임 캐릭터를 새로 생성할 때마다 게임 개발자(백엔드 개발자)한테 원하는 캐릭터의 옵션을 모두 지정해서 생성해달라고 부탁해야 하는거야. 하지만 그렇게 되면 개발자는 안그래도 바쁜데 유저의 캐릭터를 요구대로 만들어 줄 시간이 없겠지? 그리고 게임 개발자가 캐릭터를 완성해서 게임 유저에게 보내줄 때까지 게임 유저는 기다려야 되는거야. 이를 해결하려면 게임 개발자가 게임 유저에게 캐릭터 생성에 필요한 모든 옵션을 주고 게임 유저는 그 옵션 안에서 자기가 원하는 캐릭터를 조합해서 생성하는거지. 그럼 게임 개발자는 조합하는 일을 안해도 돼서 좋고 게임 플레이어는 기다릴 필요 없이 본인이 자유롭게 생성/삭제/수정을 할 수 있어서 좋겠지.

그래서 BFF를 Query모델로 사용하는 방법은 내 뇌피셜 두가지인데 첫번째는 프론트엔드 서버에서 백엔드의 데이터를 모두 받아와서 조회 모델을 생성해 저장을 해놓고 UI별로 데이터를 조합해 프론트엔드로 보내주는 방식이야. 그리고 백엔드에서 데이터 업데이트가 있다면 프론트엔드 서버로 변경에 대해 알려주고 프론트엔드 서버에서 변경된 데이터를 업데이트를 하는거지. 장점은 이미 프론트엔드 서버에 데이터가 있어서 이걸 프론트엔드에 전달하는데 걸리는 시간이 짧은거지. 그리고 프론트엔드 서버에서 데이터베이스를 따로 관리를 추가로 해야하는 단접이 있지.
그리고 두번째 방법은 그때 그때 페이지별로 필요한 데이터를 도메인별로 불러와 이를 조합해서 프론트엔드로 보내는 방식이야. 이 방법은 데이터를 불러오는데 비교적 느리겠지만 개발이 조금 쉬운 편에 속하지 않을까 싶어.

배달의 민족에서는 첫번째 방법이랑 비슷한 방법을 사용한다고 하더라고. 하지만 배민에서 정확히 어떻게 BFF를 활용하는지 모르기도 하고 내 뇌피셜로 나온 개념들이라 정확히 모르겠어. 근데 결국에 백엔드가 MSA를 도입하면 그리고 프론트엔드에서 여러 서비스에서 데이터를 받아와야 한다면, BFF가 서비스 별로 데이터를 불러와서 이를 합치는 역할을 하지 않을까 싶어.

🎯 MSA (MicroService Architecture)

MSA도 CQRS와 BFF처럼 아직 직접 개발한 건 아니지만 백엔드 개발자님이 정말 배우는 것과 배워서 나누는 것을 즐기셔서 추가로 배운 개발 지식이야. 이후에는 이것도 적용해보고 싶어.

MSA(MicroService Architecture)는 요즘 큰 서비스회사에서 많이 사용하는 개발 패턴이야. 도메인이 점점 커지기 시작하고 하나의 서비스로 모든 것을 관리하지 않고 여러개의 작은 서비스들로 나누어 각각의 서비스로 책임을 분리하는 개념인 것 같더라고. 서비스는 다른 서비스에 직접적으로 영향을 끼치지 않도록 분리하는거지. 예를 들어 하나의 서비스에서 장애가 생겼을 경우 다른 서비스에는 영향을 미치지 않도록 하거나, 또는 한 서비스가 다른 서비스에 영향을 끼치지 않고 독립적으로 확장을 할 수 있도록 하는거야. 각 서비스에 맞는 기술 스택을 다르게 쓸 수 도 있어.

Monolitic Architecture는 MAS랑 반대되는 개념인데 이건 그냥 하나의 서비스에 모든 것이 다 있는거야. Monolitic Architecture가 큰 풀장이 하나만 있는 뚝섬야외수영장이라면 MSA는 어린이 풀장, 파도풀, 어린이 파도풀, 스파온천, 어트랙션 등 다양하게 나눠져 있는 캐리비안베이와 같은거지.

MSA가 무조건 Monolitic Architecture보다 좋다고는 할 수 없어. 크고 복잡한 도메인에는 MSA가 좋지.

서비스가 큰만큼 문제가 생길 확률이 높은데 이 문제가 서비스 전체에 피해가 안가는게 좋으니까. (뚝섬야외수영장의 수도시설이 고장나면 뚝섬야외수영장은 더이상 운영자체를 못하겠지만 캐리비안베이는 고장난 풀 빼고 나머지로 운영을 하고 따로 고장난 풀을 고칠 수 있는거지). 하지만 서비스 별로 interaction이 필요한데 이게 또 고오급 기술이 필요하다고 하더라고.

그리고 Monolitic Architecture보다 Microarchitecture가 통합적인 관리가 어렵지. (뚝섬야외수영장의 구명요원들은 하나의 풀장만 관리하면 돼서 요원들끼리 정보를 관리하기 쉽지만 캐리비안베이의 요원들은 본인이 맡은 풀장 외에는 어떻게 돌아가고 있는지 정보를 공유받으려면 Talkie Walkie와 같은 장비가 추가로 필요하고 통신을 하기위한 시간이 또 들겠지).

굳이 도메인이 복잡하지도 않고 mission critical하지도 않은 간단한 시스템에 MicroService Architecture를 적용하면 개발하고 배포하고 관리하는데에 input이 필요 이상으로 소비되겠지. 이건 정말 어떤 시스템을 개발할지에 따라 달라지는 것 같아.

근데 이건 개인적인 생각이지만 객체 지향 프로그래밍 + 도메인 주도 설계를 하다보면 저절로 서비스별로 나누기 쉽게 개발이 되는 것 같더라고. 항상 미래에 대비해서 고려하며 개발하는건 좋은 자세인 것 같아. 한번 데이터 설계를 하고 데이터를 저장하기 시작하면 이를 크게 변경하는 것은 매우 힘들테니까. 어쩌면 위에서 언급했던 OOP, DDD, CQRS는 모두 MSA를 하기위한 준비단계였을지도 모르겠네.

💎 느낀 점

이렇게 나는 운 좋게 백엔드의 기본적인 개념에 대해 배우고 설계할 기회가 있었어. 사실 실제로 개발은 안하고 설계만 도와드린거라 백엔드를 개발했다고 할 수는 없지만 백엔드에 대한 이해가 조금은 생겨서 백엔드와 대화하기 조금 더 편해진 것 같아서 좋아.

그리고 조금 프론트엔드를 개발하다가 백엔드 개발에서 배운 점을 프론트엔드에서도 적용할 수 있으면 좋겠어. 백엔드와 프론트엔드는 정말 중요하게 여기는게 다른 개발이지만 결국 개발이라는 하나의 뿌리잖아. 그래서 백엔드에서 배웠던 개념이 프론트엔드에 어떤 방식으로 도움을 줬으면 좋겠어.

"💡 이렇게 5월부터 6월까지는 데이터 설계에 시간을 많이 쏟았어. 그리고 비중은 줄었지만 올해 10월까지 계속 수정해나갔어. 이런 경험을 할 수 있었던 것은 내가 정말 운이 좋았서였던 것 같아. 다음 글에서는 정말로 프론트엔드 개발에 대해 제대로 시작해볼께! (혹시 내가 잘못 알고 있는 내용에 대해서 적극적인 댓글 부탁해!)"

profile
Hi :) Future me

0개의 댓글