안녕하세요. 광고개발파트의 김한비입니다.
이 글에서는 인턴 과정으로 사내 도서 관리 서비스를 개발한 경험을 공유하고자 합니다.
배경
프로그래머스 2020 Summer Coding 여름방학 스타트업 인턴 프로그램
으로 딜리셔스에 입사한 저는 2달 동안 토이 프로젝트를 수행하는 임무를 부여받았습니다.
어떤 프로젝트를 진행해볼까 멘토와 논의하던 도중, 기존의 사내 도서 관리 시스템이 눈에 띄었습니다.
딜리셔스는 직원들의 복지를 위해 업무나 자기 계발에 필요한 도서를 무제한으로 지원하고 있습니다. 그런데 도서 구매 신청과 보유 도서 관리가 Google Docs를 이용해 이뤄지고 있었습니다. 직원들은 책 정보를 양식에 맞춰 일일이 입력해야 했고, 피플팀은 일련번호와 보유 현황을 직접 타이핑해야만 했습니다.
기존 도서 신청
기존 도서 관리
이런 불편함을 개선하고자 저는 딜리의서재
라는 이름으로 새로운 도서 관리 서비스를 만들어보기로 했습니다.
기획
먼저 기존 프로세스를 파악하려고 했습니다. 도서를 신청해본 적 없는 인턴으로서, 새로운 도서 관리 시스템이 왜 필요한지 생각해 보기 위함이었습니다. 서비스의 깊은 이해가 선행되어야 목적에 맞는 개발을 수행할 수 있다 믿기 때문에 간단한 프로세스라도 직접 경험하며 불편함을 느껴보려 했습니다.
그러고 나서 피플팀 담당자님, 멘토와 세 명이 여러 번의 회의를 진행했습니다. 서비스 운영자로서 필요한 필수 기능이 무엇인지, 어떤 점이 개선되었으면 좋겠는지, 장기적으로 무슨 기능이 더 추가되길 원하는지 생생한 이야기를 들을 수 있었습니다. 저 또한 기존 프로세스에서 궁금했던 점을 질문할 수 있었습니다.
그렇게 기능 목록을 도출할 수 있었고, Kakao Oven을 이용하여 프로토타이핑을 진행했습니다. 학생 때 팀 프로젝트를 진행하면서 팀원들의 작업을 지켜봤던 경험은 있었지만 제가 직접 만들어본 것은 처음이었습니다. 옆에서 지켜볼 때와 달리 직접 프로토타이핑하는 일은 생각보다 신경 써야 할 것이 많았고 페이지 간의 연결 고리도 자세하게 작성해야 했습니다. 게다가 간단한 디자인이 포함되는 작업이라, 미적 감각이 부족한 저에겐 크나큰 난관이었습니다.
디자인, 너무 어려워…
그렇지만 멘토의 도움으로 페이지를 하나하나 완성해나갈 수 있었습니다. 기능 목록만 도출했을 땐 어떻게 화면을 구성해야 하고 어떤 기능들이 위치할까 정말 모호했었는데, 구체적인 화면으로 그려내니 개발의 방향성이 좀 더 뚜렷해졌습니다. 또한 프로토타이핑 결과물을 피플팀과 공유하여 부족한 부분을 보완할 수도 있었습니다.
프로토타이핑 with Kakao Oven
개발
구체적인 기획을 완성했으니 이제 본격적으로 서비스를 만들 단계입니다. 멘토와 저는 제일 먼저 어떤 기술 스택을 사용할 것인지 결정했습니다.
API 서버는 주로 저희 파트에서 사용되는 기술들을 사용하여 개발하기로 했습니다. 이에 더해 기능을 개발하면서 필요한 jsoup이나 spring security 등을 추가로 도입했습니다.
- Spring Boot (2.3.2)
- Spring Data JPA
- Querydsl JPA
- MySQL (5.7.12)
웹 서버는 제가 과거에 사용해봤던 React를 사용하여 만들기로 했습니다. 사실 딜리셔스는 Vue.js를 사용해서 광고 관련 웹 서버를 개발하고 있습니다. 그렇지만 이번 프로젝트는 사내 전용 서비스이며, 기능 변경이 잦지 않고, 프론트 구현이 프로젝트의 중심이 아니기 때문에 저에게 익숙한 프레임워크를 사용하기로 했습니다. 이 외에도 기능 완성에 필요한 react-google-login이나 JSON Web Token 등을 추가로 사용했습니다.
- React (16.13.1)
- mobx (5.15.4)
- material-ui & styled-components
- axios
이렇게 대략 어떤 기술들을 사용할지 정한 뒤 본격적인 개발에 앞서 몇 가지 준비를 거쳤습니다. 먼저 API 목록을 간단하게 정의하여 Notion에 정리했습니다. 그러고 나서 Swagger를 사용해 API 명세서를 만들었습니다. 이렇게 요청 및 응답 데이터를 구체적으로 정의하면 웹 서버와 API 서버가 데이터를 더욱더 수월하게 교환할 수 있습니다. 참고로 저는 SwaggerHub라는 서비스를 이용했지만, 저희 파트에선 별도의 yaml 파일로 명세서를 관리합니다.
API 목록 도출
API 명세서
그 후 MySQL Workbench를 이용해서 EER 다이어그램을 작성했습니다. 다이어그램만 작성해도 그에 맞는 쿼리를 자동으로 생성해 주기 때문에 매우 편리합니다. 학생 때 여러 번 해 본 작업이라 툴을 다루는 건 어렵지 않았는데, 네이밍은 여전히 어려웠습니다. 신청 정보를 담는 request 테이블이 특히 까다로웠습니다. 해당 테이블 명을 대체할 마땅한 이름이 있다면 추천 부탁드립니다!
EER Diagram
프론트엔드 측면에선 크게 2가지를 준비했습니다. 먼저 Atomic Design이라는 방법론을 학습했습니다. 과거 React를 사용하여 토이 프로젝트를 진행할 때, 확고한 기준 없이 컴포넌트를 나누다가 코드가 뒤죽박죽 얽혔던 경험이 있었습니다. 그때의 실패를 바탕으로 이번엔 뚜렷한 기준으로 컴포넌트를 설계해보고 싶어 적용해봤습니다. Atomic Design은 물질을 이루는 가장 기본 단위인 ‘원자’를 시작으로, 분자, 유기체, 템플릿, 페이지와 같은 큰 단위로 점점 확장해나가는 디자인 방법론입니다. 라인에서 발행한 Atomic Design 적용기를 참고하여 이해할 수 있었습니다.
그러고 나서 React의 상태 관리를 위해 MobX를 공부했습니다. 상태를 관리하는 라이브러리가 없다면 비즈니스 로직이 컴포넌트에 집중될 수 있고, 다양한 계층 사이에서 컴포넌트 간 데이터 교환이 어려워집니다. 보통 React를 사용하면 Redux를 상태 관리 라이브러리로 채택하는데, 저는 Spring과 유사한 레이어 아키텍처를 가진 MobX를 적용하여 간결하게 상태를 관리하고 싶었습니다. 우아한형제들 기술 블로그에서 발행한 React에서 Mobx 경험기가 많은 도움이 되었습니다.
MobX 컨셉
이렇게 기본적인 개념을 공부한 뒤 딜리의서재
를 개발하기 시작했습니다. 혼자서 웹과 API를 동시에 개발해야 했고, 스프링 부트로 제대로 된 프로젝트를 만들어본 적도 없었으며, MobX와 같은 새로운 라이브러리를 사용하면서 우여곡절이 많았습니다. 하나의 기능을 완성하는데도 많은 시간이 걸렸는데, 지식이 부족하다 보니 간단한 문제 해결도 오랜 시간이 필요했습니다. 개발하는 시간보다 학습하는 시간이 더 많았던 것 같기도 합니다.
수많은 문서 학습의 흔적
그래도 멘토의 도움으로 어려웠던 부분을 조금씩 해결해나갈 수 있었고, 겉보기에 멀쩡한 (하지만 사소한 버그가 엄청 많았던) 웹서비스를 완성할 수 있었습니다. 서비스 사용자는 도서 신청, 도서 목록 조회, 신청 도서 관리 기능을 이용할 수 있습니다. 운영자는 이에 더해 신청 확정 및 반려 기능을 이용할 수 있습니다. 많은 기능이 있는 것은 아니지만, 누군가 실질적으로 사용할 수 있는 서비스를 구현했다는 점에서 매우 뿌듯했습니다.
도서 신청
전체 도서 목록
발표 및 회고
인턴 기간 막바지에는 프로젝트의 구체적인 구현 과정과 결과물을 공유하는 날이 있습니다. 이를 위해 기획부터 구현, 핵심 개념, 학습 내용, 진행 과정, 아쉬웠던 점 등을 담아 Keynote를 만들었고, 광고검색파트 팀원들과 CTO님이 있는 자리에서 발표하게 되었습니다.
발표를 위한 Keynote 일부분
발표를 마치고 나니 복잡한 감정과 다양한 생각들이 몰려왔습니다. 인생 처음으로 인턴이 되어 실무 프로세스를 따라 개발하다 보니, 아무래도 아쉬운 점이 많았습니다. 개발 외적으로 고생했던 점은 다음과 같습니다.
- 맥북 사용법
- 일정 및 컨디션 관리
저는 딜리셔스에 입사하기 전까지 평생 윈도우만 사용해왔던 골수 윈도우 유저입니다. 그런데 인턴으로 입사한 날 저에게 주어진 맥북은 정말 큰 장벽이었습니다. 한/영 전환부터 프로그램 이동까지 간단하고 작은 작업이라도 제겐 너무 어색했습니다. 특히 트랙패드를 적절히 사용할 때까지 오랜 시간이 걸렸습니다. 그런데 지금은 윈도우에서 계속 Caps Lock을 누르며 ‘한글이 왜 안되지?’’ 불평하는 제 자신이 보입니다 (^_^;
일정과 컨디션을 관리하는 일도 어려웠습니다. 불규칙한 리듬으로 개발하고 공부하던 저는, 회사원의 근무 시간에 맞춰 작업하고 퇴근 이후에 공부하는 생활에 익숙해지기 어려웠습니다. 게다가 인턴 기간 중 1주일의 동대문 휴가가 있었습니다(날이 더운 8월 중순, 딜리셔스는 동대문의 휴식 기간에 맞춰 여름휴가를 즐깁니다!!) 7월부터 시작되는 인턴 생활의 중간에 갑자기 긴 휴가를 맞이하니, 더욱더 컨디션을 조절하기 어려웠습니다. 오히려 쉴 땐 푹 쉬고, 작업할 땐 집중하여 개발했더라면 좀 더 품질 높은 코드를 완성할 수 있었을 것이라는 후회가 남습니다.
개발 측면에서 아쉬웠던 점은 다음과 같습니다.
- 책임이 명확하게 분리되지 않은 코드
- 테스트 미비
- 스타일과 로직이 분리되지 않은 컴포넌트
지금은 도메인 모델을 중심으로 각 객체에 책임을 부여하며 코드를 구성하지만, 당시엔 좋은 코드에 대한 기준을 세우지 못했습니다. 그러다 보니 하나의 서비스 클래스가 비대해지곤 했고, 적절히 공통 메소드를 분리하지도 못해 코드가 매우 복잡해지게 되었습니다. 도서 관리 기능들이 간단해서 그렇지, 실무의 복잡한 프로세스를 이런 방식으로 구현했다면 유지 보수가 정말 어려웠을 것입니다.
테스트 또한 부족했습니다. ‘기능만 잘 구현해서 버그가 없으면 되지, 굳이 테스트까지 만들어야 할까?’ 라고 생각해서 유닛 테스트를 많이 생략했습니다. 일정을 맞추는 것에 급급했습니다. 그런데 나중에 실무에 투입되면서 유지 보수가 잦은 프로젝트를 개발하다 보니, 테스트 코드의 중요성을 깨닫게 되었습니다.
컴포넌트는 React에서의 이야기입니다. 저는 스타일을 컴포넌트 내부에 넣지 않고 독립된 코드로 관리하기 위해 styled-component
를 사용했습니다. 라이브러리를 정확하게 이해하지 못하니, 적용하기 어려운 코드가 있었고, 이를 인라인 스타일이나 Material-UI의 스타일 라이브러리를 이용해서 해결하곤 했습니다. 그러다 보니 각 컴포넌트의 스타일 코드가 뒤죽박죽 혼란스러운 형태를 가지게 되었고, 내부 로직과 명확히 나뉘지 않아 해석하기 어려운 코드가 되어버렸습니다. 지금 프론트쪽 코드를 보면 개선해야 할 부분을 상당히 많이 발견할 수 있어 아쉽습니다.
마무리
이렇게 발표와 회고를 마쳤고, 저는 정규직으로 전환되어 광고검색파트에서 광고플랫폼의 API 서버를 개발하고 있습니다. 그 후 여유 시간이 있을 때마다 피플팀 담당자님에게 의견을 구하며 추가 기능을 개발했습니다. 아래 사진에서 보이듯 보유 중인 도서의 대여 신청 버튼을 누르면, 해당 대여자의 슬랙으로 메세지가 전송되고 대여자는 도서 대여 여부를 결정할 수 있습니다. 액션에 따라 콜백 메세지가 또 슬랙으로 전송됩니다.
이 외에도 엑셀로 Google Docs의 신청 정보를 마이그레이션할 수 있는 기능, 검색 기능 개선, 신청 도서 구매 확정 시 슬랙 메세지 전송 등을 작업했습니다. 상용 배포가 이뤄지기 전이라 다양한 피드백은 들을 수 없었지만, 파트원들과 담당자분이 의견을 주시며 서비스를 확장해나가는 과정이 즐거웠습니다.
대여 신청 기능
슬랙 대여 신청 메세지
꼭 누군가 사용해주지 않더라도, 불편한 점을 개선하기 위해 새로운 서비스를 만들고 사용자의 행복을 상상하는 일은 항상 뿌듯합니다. 인턴 과정마다 진행하는 프로젝트는 조금씩 다르겠지만, 현재 인턴으로 활동하고 계시는 분들도 이와 비슷한 즐거움을 느낄 수 있을 거라 생각합니다. 앞으로도 딜리셔스의 경험에 많은 관심 가져주세요. 감사합니다.
김한비
딜리셔스 백엔드 개발자
"꾸준히 쌓아가기"