🎧 Hype
‘음악 추천 및 대결 서비스’로 사용자들이 음악을 추천할 수 있는 공간을 제공하고 대결을 통해 랭킹을 산정하여 재미뿐만 아니라 음악을 잘 아는 사람이 추천하는 음악에 대한 접근성을 높인 서비스
❔ 주제 선정 배경
해당 서비스의 주제를 선정한 이유는 제가 좋아하는 음악들을 다른 사람들에게 추천해주고 싶은데 그 공간이 마땅치 않아서 카카오톡 프로필 뮤직이나 인스타 스토리에 주로 게시를 했었습니다. 근데 그렇게 올리면 ‘이 음악 좋다’와 같은 반응을 보고 싶은데 그게 쉽지 않았고 아는 사람들에게만 추천이 가능하다는 점이 아쉬웠습니다.
그리고 제가 생각할 땐 저보다 ‘힙합/랩’ 이란 장르에서 더 좋은 노래를 많이 아는 사람이 없다고 생각이 되어서 음악 대결을 통해서 겨뤄보고 싶었고 지더라도 더 좋은 노래를 알아갈 수 있을 것 같아서 이런 서비스를 기획하게 되었습니다.
⏳ 프로젝트 과정
✅ 프로젝트 주제 선정 과정
이전까지의 교육 과정에서는 기획이라는 부분이 빠져있었습니다. 1차 개인 프로젝트에서도 우리가 배운 부분에서 ‘커피숍 프로젝트’와 유사한 프로젝트를 만들어보자라고 이해를 해서 비슷하게 할 수 있는 간단한 쇼핑몰 서비스를 만들었고 2차 백엔드 팀 프로젝트에서는 클론 코딩을 하라고 해서 존재하는 서비스 중에서 재밌을 것 같은 ‘인터파크’를 따라했습니다. 그러다 보니까 기획은 처음 했는데 주제 선정이 너무 어려웠습니다.
저는 최대한
내가 좋아하고 이용할 것 같은 서비스에 초점을 맞춰서 2개의 주제를 선정했는데
- 플레이리스트 공유 서비스
- 뭐 입지? (스타일 추천 및 공유 서비스)
위와 같은 2개의 프로젝트 주제를 준비해서 회의에 참여했습니다.
팀원들은 각자가 원하는 주제를 선정했고 해보고 싶은 주제에 각 3개씩 댓글을 달기로 했습니다.
그 중 댓글을 가장 많이 받은 3개의 주제가 뽑혔고 이 주제만을 가지고 투표한 결과 최종적으로
‘플레이리스트 공유 서비스’가 채택되었습니다.
📝 프로젝트 기획 과정
처음 제시된 플레이 리스트 공유 서비스는 음악을 듣는다에 더 치중되어 있다는 생각이 들고 대결을 구성하기도 어려운 점이 있을 것 같다는 생각이 들어서 ‘음악 추천 및 대결 서비스’로 주제를 수정했습니다.
해당 프로젝트에서 중요한 기능은 크게 2개라고 생각했습니다.
- 음악을 추천한다.
- 음악으로 대결을 한다.
다른 서비스들과의 차이점은 음악을 이용한 대결이라는 생각이 들었습니다. 근데 음악 추천도 빠질 수 없기 때문에 어떻게 둘 다 활성화 시킬 수 있을까 생각하다가 추천한 음악으로만 대결을 할 수 있게 구성하면 둘 다 활성화 될 수 있지 않을까? 라는 생각으로 이런 규칙을 만들었습니다.
어떻게 하면 대결을 더 재밌게 구성할 수 있을까라는 생각에서 랭킹 시스템 도입과 숏츠 형식의 투표 시스템이 도출되었습니다. 랭킹 시스템은 성취감을 얻을 수 있고 상위 랭킹의 유저가 추천한 음악들을 확인할 수 있게 하여 많은 사람들에게 투표를 받은 음악들을 더 쉽게 확인할 수 있게 기획했습니다. 그리고 숏츠 형식의 투표 시스템은 유저가 클릭해서 들어가야 하는 깊이를 하나 줄여서 조금 더 손쉽고 게임같은 느낌으로 재밌게 구성해보자는 생각으로 기획했습니다. 또 대결 신청 시 대결권을 줘서 게임적인 느낌뿐만 아니라 마구잡이의 대결을 막자는 생각으로 이 부분을 기획하게 되었습니다.
💭 프로젝트 회고
FE와의 협업
- 스프린트 관련처음 저희 팀이 스프린트 기간과 스크럼 시간을 어떻게 할까라는 토의를 시작할 때 프론트측에서는 스프린트 기간은 1주일을 가져가고 스크럼은 일주일에 한번 하면서 필요할 때 연락해서 물어보는 형식을 취하자고 제안했습니다. 하지만 제가 생각할 때는 스프린트 기간이 초반엔 더 짧았으면 좋을 것 같았고 스크럼은 매일매일 가져야 진행 상황을 FE, BE 서로서로 알 수 있을 것 같다는 생각이 들어서 이와 같은 제안을 했습니다. FE는 스프린트의 의미가 스프린트마다 의미있는 기능을 만들어야 하는데 일주일보다 더 짧다면 그게 불가능할 것이라고 말했고 BE도 이를 납득하고 최종적으로 스프린트 기간은 일주일을 가져가고 스크럼은 매일 21:00에 진행하며 스프린트 종료 시 마다 스프린트 회고를 진행하기로 결정되었습니다.
- 실제로 이 방법으로 진행하면서 FE들도 매일 스크럼을 진행하는 것에서 진행 정도를 알 수 있어서 좋은 것 같다고 말했고 스프린트 회고를 진행하면서 다음 스프린트 때 이를 수정하고 조금 더 발전된 스프린트를 진행할 수 있어서 좋았다고 말했습니다.
- 와이어 프레임이전에 진행했던 2차 프로젝트(백엔드 협업)에서는 클론 코딩임에도 화면 분석없이 저희의 생각대로 코드를 짰는데 그래서 API 초안을 짤 때도 어려운 점들이 있었고 머리 속으로 그려지는 것들이 개인마다 다르다 보니까 생각이 하나로 모아지지 않고 진행되었던 부분들이 있었습니다.팀원 모두 의견을 많이 제시해주고 자신의 생각이 뚜렷해서 더 좋았던 것 같습니다. 무작정 내 말이 맞아라고 우기는 것이 아니라 근거를 바탕으로 의견을 제시했고 다른 팀원의 의견에 대한 수용도 적극적으로 해서 정말 원활하게 협업이 진행되었습니다.
- 그래서 생각했던 것이 화면을 먼저 구성하면 좋을 것 같았고 이번 프로젝트에서는 먼저 와이어 프레임을 짜면서 화면을 같이 구성했습니다. 이런 과정을 거치니까 API 초안을 짤 때 어떤 데이터를 내려주면 좋을 지를 더 쉽게 생각할 수 있었던 것 같습니다.
- 개발 속도이번 프로젝트 이전까지는 저는 제가 생각하는 방식의 단위 테스트만 짜고 통합 테스트를 짠적이 없었습니다. 그래서 통합 테스트를 어떻게 짜야하는지, 단위 테스트를 이런 식으로 짜는게 맞는 건지에 대한 궁금증이 생겨서 단위 테스트 책을 읽고 이를 해당 프로젝트에 적용해보려고 하다 보니까 기능 구현보다 테스트에서 시간이 4~5배로 걸려 API 명세서가 나오는데 시간이 오래 걸렸습니다. 저뿐만 아니라 다른 BE들도 테스트를 꼼꼼하게 짜려고 하다 보니 BE 팀 전체의 개발 속도가 더뎠습니다.그래서 저희 BE 팀은 가장 중요하고 이때까지 많이 사용하지 않았던 통합 테스트를 위주로 테스트 코드를 짰고 이와 함께 기능 API를 배포하니까 API 명세가 나오는데 까지 걸리는 시간이 확 줄었습니다. 그리고 3차 스프린트를 진행할 때는 더 빠르게 코드를 짤 수 있었습니다. 이 과정을 통해서 우선순위가 무엇인지를 잘 생각해볼 수 있었고 무조건 모든 테스트 코드를 짜놓고 배포하는 것이 아닌 꼭 필요한 테스트만 넣고 배포 후에 테스트 코드를 짜던가 아니면 운영 중 터지는 부분이 생겼을 때 거기에 대한 테스트 코드를 짜넣는 것도 방법이라는 생각이 들었습니다.
- 그러다 보니까 FE에서는 화면 구성을 마치고 퍼블리싱까지 끝냈는데 API가 나오지 않아서 불만도 생기고 프로젝트가 아닌 개인 공부를 진행하면서 기다리는 시간이 생겼고 팀 스크럼에서 이런 불만 사항을 토로했습니다. BE 팀은 나름대로 최선을 다해서 개발하고 있다 보니까 미안하면서도 어쩔 수 없는 거 아닌가라는 생각이 들었고 이런 부분에 대해서 멘토님께 어떤 방식으로 진행하면 좋을 지에 대해서 여쭤보았습니다. 멘토님은 테스트를 줄이고 API를 뽑아 내는 것에 집중하라고 말씀해 주셨습니다. 테스트는 기능을 뽑아내고 뒤에서 계속 넣을 수 있기 때문에 꼭 필요한 테스트만 넣고 먼저 API를 배포하라고 말씀하셨습니다.
- API 명세 수정API 초안을 이용하여 회의를 진행했음에도 디자인이 나오고 나서 화면을 구성하면서 어떤 데이터가 추가적으로 필요하다는 요청을 많이 받았습니다. BE 팀 진행을 리드했던 팀원이 이런 요청이 많이 생길 것이라서 기능 구현을 조금 더 일찍 끝내고 이런 요청에 맞게 수정해주는 시간을 둬야 할 것 같다고 말했는데 저는 최대한 꽉꽉 채워서 더 많은 기능을 만들어 내는 것이 맞지 않나 라는 생각을 했습니다.
- 하지만 이런 여유 시간을 두지 않았으면 서비스의 완성도는 떨어지고 저희가 구현한 API가 실제 서비스에는 사용되지 않는 상황이 발생했을 것 같다는 생각이 들었습니다.
BE 간의 협업
- 팀원과의 의견 충돌팀 프로젝트가 시작되기 전에 FE, BE 모두 조금의 여유 시간이 생겼고 FE들은 방학을 가졌습니다. 제가 생각했을 때는 이 기간에 주제가 정해지면 바로 개발을 할 수 있게 컨벤션(코드 컨벤션, PR & 커밋 컨벤션 등), 프로젝트 세팅(JAVA 버전, Spring 버전 등), 개발 환경 세팅 (AWS, DB 등) 등 결정하고 세팅해야 할 것들을 미리 해놔야 한다는 생각이 들었습니다. 하지만 다른 팀원은 충분히 쉬고 프로젝트 시작날부터 빠르게 하면 된다는 생각을 가지고 있었습니다. 그래서 BE 팀 회의를 진행할 때 다른 팀원은 자신의 생각을 말했고 저는 이해가 되지 않았지만 일단 알겠다고 말했습니다.다른 팀원은 협업은 혼자 진행하는 것이 아닌데 왜 독단적으로 이러냐 아까 동의하지 않았냐라고 말을 해서 제 생각과 걱정을 쏟아내듯이 차근차근 말했습니다. 다른 팀원은 이해가 된다고 하면서 다른 의견이 있으면 먼저 말을 하고 일정을 잡고 하면 좋을 것 같다고 말했습니다.
- 이 경험을 통해서 협업에서 중요한 것은 내 생각을 말하고 팀원 간 이를 조율하는 것이라고 느꼈습니다. 사람들은 모두 다른 생각과 다른 가치관을 가지는데 막무가내로 자신의 생각을 주입하려고 하고 자신의 의견을 독단적으로 진행하려 했던 제 모습을 반성하게 되었고 이후 협업을 진행할 때는 의견과 함께 근거를 말해서 이해시키는 것을 우선 시 하려고 했습니다.
- 하지만 그 날 저녁부터 걱정이 너무 커지기 시작했고 그래서 해야할 부분을 전부 다 적어서 당장 내일 회의를 진행해서 결정할 것들을 다 결정하고 해야할 것들을 다 분배하자고 말을 했습니다.
- 각 스프린트 마다 MVP 하나의 기능 배포해당 팀 프로젝트에서 저희는 매 스프린트마다 MVP에 해당하는 하나의 기능을 배포하는 것을 목표로 하였고 이를 이루기 위해서 크게는 같은 기능 아래에서 세부적 기능을 분배했습니다. 이렇게 진행하다 보니까 1차 스프린트 때는 못느꼈는데 2차, 3차가 되니까 컨플릭트가 생기고 다른 사람이 짠 테스트를 바꿔야 하는 경우가 종종 발생했습니다.
- 그래서 도메인 별로 기능 구현을 나누는 이유가 이런 것이구나 라는 생각이 들었습니다. 하지만 이런 식의 개발에서 좋았던 점은 배포 시마다 QA 하기가 좋았던 것 같습니다. 또 하나의 기능을 같이 만들어 가다 보니까 전체적인 서비스 이해도가 이전 프로젝트보다 훨씬 좋았던 것 같아서 어떤 식으로 분배해서 개발을 할 지는 선호도의 차이라는 생각이 들었고 저는 컨플릭트가 생기고 다른 사람의 코드에서 문제가 생기는 부분이 발생할지라도 기능 단위로 분배해서 개발하는 것이 좋다고 느낀 이유는 위에서 말했던 서비스 이해도에서 너무 크게 차이가 난다고 경험을 해서 저는 이를 선호하는 것 같습니다.
개인 개발 시 발생한 문제 해결
- CORS 문제 발생우리 서버에서 발생하는 CORS 문제는 소셜 로그인을 구현한 팀원이 CORS 설정 configuration을 잘 설정해줘서 문제가 없었는데 프론트 측에서 사용하는 외부 API인 애플뮤직 API가 문제였습니다. 데스크탑 버전으로 API 요청을 했을 때와 갤럭시와 같은 안드로이드로 모바일 버전으로 API 요청했을 때는 아무런 문제가 없는데 IOS에서 모바일 버전으로 접근할 때만 CORS 문제가 발생했습니다. 구글링을 해봐도 이를 해결할 수 있는 명확한 방법이 나오지 않아서 IOS의 모바일 버전에서만 이런 문제가 발생한다면 요청 위치를 CORS가 발생하지 않는 곳 하나로 고정시키자는 생각이 들었고 백엔드 서버에서 API를 만들어서 사용자가 입력한 검색어를 이용하여 대신 요청하는 API를 만들었고 이를 해결할 수 있었습니다.
- 비록 네트워크 요청이 클라이언트에서 해당 애플뮤직 API로 1개가 날아가던게 백엔드 서버를 거치면서 2번 요청하게 되는 구조긴 하지만 이를 해결할 수 있었고 또 백엔드에서 데이터에 대한 처리를 할 수 있다는 것이 좋았습니다. 해당 서비스에서 저희는 api 응답 정보에 담긴 previewUrl에 담긴 파일을 통해서 노래를 재생하는데 검색 결과 중 이 부분이 공백으로 재생 파일이 담기지 않은 경우가 존재했고 이를 처리하지 못하고 있었는데 이런 방식으로 구성을 하고 응답 값에 previewUrl이 공백인 경우를 제외하는 처리를 할 수 있었습니다.
- 전략 패턴 도입 고려구현된 API 중 하나의 API에서 쿼리 파라미터로 인해 분기가 4개 정도로 나뉘는 부분이 생겼습니다. 이 분기를 없애고 싶어서 디자인 패턴 중 하나인 전략 패턴을 이용해보자는 생각이 들었고 적용해보았습니다.이 경험을 통해서 제가 생각할 때 전략 패턴을 도입해야 하는 경우는 구현체가 확장될 일이 잦고 알고리즘 자체가 복잡하여 가독성이 떨어지는 경우 유지/보수 및 가독성 측면에서 전략 패턴을 이용했을 때 이점이 많은 경우라는 생각이 들었습니다.
- 해당 분기 전략에 대한 인터페이스 전략을 생성하고 각 분기에 맞는 구현체 클래스들을 만들었고 내부에 오버라이딩한 메소드를 구현했습니다. 이렇게 구현하고 보니까 인터페이스 1개에 구현체 클래스가 4개가 나오게 되었습니다. 정말 단순한 분기 처리인데 이렇게 많은 파일들이 생성되는 것이 맞을까라는 생각이 들었습니다. 추가적으로 쿼리 파라미터가 더 생길 일이 굉장히 드물고 분기에 따라 실행되는 알고리즘들이 정말 간단했기에 전략 패턴을 도입함으로써 코드 가독성이 더 떨어지고 관리해야 할 파일들이 불필요하게 늘어난다는 생각이 들었고 적절하게 디자인 패턴을 사용하는 것이 아니라는 생각이 들어 원 상태로 돌려놨습니다.
느낀 점
제가 프로젝트를 진행하면서 느꼈던 가장 큰 감정은 힘듦보다는 즐거움이었습니다. 내가 좋아하는 도메인과 진짜 이용하고 싶은 서비스를 만드니까 더 개발하고 싶고 더 완성도 있게 만들고 싶다는 생각이 점점 커졌습니다. 이런 경험을 통해서 직장을 선택할 때도 도메인을 더 고려해야겠다는 생각이 들었습니다.
그리고 어려운 기술 사용하는 것이 큰 의미가 없다는 생각이 들었습니다. 결국은 서비스를 만들기 위해서 기술을 사용해야 하는 것인데 이때까지의 저는 기술을 사용하기 위해서 서비스를 만들었던 것 같습니다. 이런 이런 기술을 사용해야 하니까 이런 기능을 넣어야 한다는 생각으로 서비스를 구성했습니다. 또 너무 그냥 CRUD만 있는 서비슨데? 이런 생각이 들면 조금 더 고급 기술을 사용해야겠다와 같은 생각으로 기술 도입을 시도했습니다. 하지만 이 프로젝트를 진행하면서 CRUD만으로도 완성도 있고 재미있는 서비스를 제공할 수 있구나를 느꼈고 유저가 원하는 기능이 있을 때 그 기능을 구성하기 위해서 기술을 도입하는 것이 해당 서비스의 핏에 더 맞는 기능을 추가할 수 있구나를 느꼈습니다.
마지막으로 백엔드 관련 경험이 전혀 없는 상태로 들어오긴 했지만 제가 했던 협업 중에 가장 원활하고 걱정이 덜 했던 서비스였던 것 같습니다. 너무 재밌게 했고 팀원들과 합이 가장 잘 맞았던 것 같습니다. 그리고 프레젠테이션도 제가 생각한 것보다 더 반응도 좋고 긴장도 덜 해서 마무리까지 좋았던 것 같습니다. 앞으로 해당 서비스를 더 발전시키고 싶은 마음이 커서 리팩토링 하면서 추가적인 기능을 개발하고 싶습니다. 회고 끄으읕!!
Uploaded by
N2T