Elice Ai 트랙 3기에 참여 중이다.
6개월의 기간동안 웹 front / back (개인프로젝트 2주), 데이터분석(데이터분석을 이용한 팀프로젝트), 인공지능(인공지능을 이용한 팀프로젝트 5주)
벌써 중간지점을 지난 데이터분석(데이터분석을 이용한 팀프로젝트) 의 프로젝트 결과물을 회고 해보고자 한다. 나를 포함한 5명의 팀원들과 함께 했으며, 프론트엔드 1명, 백엔드 2명, 데이터분석 2명이 한 팀이 되었다. 나는 도대체 프론트엔드가 1명인 이유를 알지 못했는데, 그저 지원자가 적어서였다. 사실 많이 부담되었다. 피해는 주고 살지 말자
나의 사회생활 신념인데, 모자란 코딩 실력이 피해를 왕창 줄 것 같기 때문이다. 그래도 최고의 팀원들을 만나 너무 즐겁게 프로젝트를 끝낼 수 있었다. (수 많은 밤을 지새우고...)
그래서 급하게 nomad coder
의 react
기초 강의를 들었다. 불행 중 다행히 영화추천서비스와 비슷한 주제의 강좌여서 많이 참고할 수 있었다.
ReactJS로 영화 웹 서비스 만들기 (고마워요 니꼬)
막상 닥치니까 더 열심히 공부하게 되었다. 필요한 것들을 검색하고 적용하는 과정에서 많이 공부가 되었다. 또한 팀원들과 함께 소통하고 기획하고 진행해가는 순간순간 개발자가 되어가고 있다고 느꼈다. 할 수 있는 것과 할 수 없는 것을 구분하고, 해야 하는 것과 하지 말아야하는 것을 구분했다. 좋은 일의 가치는 좋은 팀원들과 일하는 것
이었던 나의 작은 신념이 개발자를 선택하고 실현된 기분이 들어 매우 감사했다.
이제 진짜 프로젝트를 소개해보고자 한다.
OTT서비스를 기반으로 코로나시대의 유의미한 데이터를 활용해 만드는 프로젝트였다. 기존에 유저취향을 기반으로 하는 영화추천서비스는 이미 너무나 잘 되어있고, 새로운 게 무엇이 있을까 고민이 되었다.
코로나블루
근 2년간 코로나로 인해 사람들의 감정 변화가 심하게 일어났다. 주로 부정적인 감정이 었는데, 걱정, 스트레스 불안, 두려움의 증가폭이 가장 컸다.
우리는 감정과 음악의 상관관계를 조사하였고, 스트레스를 받을 때 노래를 듣는 것이 기분전환에 도움이 된다는 자료를 참고 하게 되었다. 이를 기반으로 자신이 좋아하는 OST와 기분을 고르고 이를 통해 지금 상태와 알맞는 OST가 담긴 영화를 추천해주는 서비스를 기획하게 되었다.
우리는 Nexflix, hulu, disney, prime의 정보가 담긴 캐글 OTT데이터를 기본으로, spotify music API, 네이버영화의 정보들을 크롤링해서 활용하였다.
음화당, 음악을 좋아하는 당신께 이 영화를 드려요.
API 연결
실제로 back-end 개발자가 DB를 만들어 API get
post
로 연결했다. 처음 연결된 그 순간의 희열은 잊을 수 없다. 어디서 비동기를 사용해야 하는지 아직도 정확히 알진 못하지만, 느낌은 잡았다. 일단 front와 back의 정확한 의사소통이 중요하고, 우리만의 언어로 데이터 송신을 잡아야 한다는 것을 정확히! 틀림없이! 느꼈다.
음악재생
해본 적이 없었다. 일단 잘 몰라서 라이브러리를 아무거나 가져다가 썼다. 덕지덕지란 말이 잘 어울렸다. 결국 순정이 좋다고... <audio tag>
를 써서 구현하게 되었다. hover 시 음악이 재생되게 했다. 라디오버튼 뒷면에는 영화의 장르가 달려있다. 여기서 user는 음악을 듣고 장르를 선택하는 것이다.
슬라이더
여기서도 무분별한 라이브러리의 사용의 폐해를 다시 한 번 겪었다. @mui slider
컴포넌트를 사용했다. 사용하는 것까진 편해서 좋았는데 style 구현이 너무나도 힘들었다. 각 질문 뒤에는 음악의 feature 값을 정하는 요소들이 포함되어있었다.
API post
앞에서 받은 2가지의 user input(movie genre, music features) 값을 모아서 DB에 API post를 보냈다. 이를 기반으로 데이터분석을 해 사용자가 좋아할만한 영화음악을 받아왔다.
antd : 대륙의실수
영화음악을 사용자에게 어떻게 보여줄까하다가 antd라이브러리를 보았다. 샤오미에 이어 대륙의 실수라고도 불리우는 디자인 라이브러리는 정말 간편했다. 하지만 위와 마찬가지로 왜 사용해야하는지에 대한 생각을 고려하지 않았다. 그래서 활용도차원에서 제약이 있었다. css를 통해 포스터 이미지를 앨범커버처럼 구현하여 음악을 재생시켰다.
API 렌더링 문제
영화의 포스터 등을 www.soundtrack.net에서 긁어오는데 아래처럼 한 두개씩 많을 땐 전체가 실패하는 경우가 생겼다. 처음엔 대수롭지 않게 여겼는데... 계속 발생하는 것을 보고 서비스의 완성도 측면에서 큰 문제가 될 것이라 생각이 들었다. 바로 오피스아워 시간에 코치님과 면담을 요청했고, error를 캐치해서 error 발생 시 api를 재요청하는 코드를 작성했다.
function retryImage(imageSrc, retry, alt) {
return new Promise((resolve, reject) => {
function helper(src, remain, alt) {
const imageTag = document.createElement("img");
imageTag.src = src;
imageTag.alt = alt;
// imageTag.style = "width: 100%; height: 320px;";
imageTag.onload = () => {
console.log("성공");
resolve(imageTag);
};
imageTag.onerror = () => {
console.log("실패");
if (remain === 0) return reject();
helper(src, remain - 1);
};
}
helper(imageSrc, retry, alt);
});
}
retryImage function을 만들어 document.createElement("img")
를 만들어 imgtag가 onload 되었는지 onerror를 받았는지 확인한다.
HTML 문서에서, Document.createElement() 메서드는 지정한 tagName의 HTML 요소를 만들어 반환합니다.
여기서 우리는 error를 확인하고, 그 것을 잡아낼 수 있었다. error를 통제할 수 있는 것만으로도 엄청난 성과라고 하셨다.
onerror
가 확인 되었늘 때 helper
함수를 재실행한다. 5회로 지정해준 횟수만큼 실행하고 최종적으로 실패 시 다른 문구가 뜨도록 설정해놓았다.
다행히도 해당 이미지의 url 은 1회 대부분 1회 재실행으로 불러올 수 있었다.
img를 불러올 때 5번의 재시도 로직을 넣어 버그를 제한했다. (현직 프론트엔드 코치님과 3시간 가량 라이브코딩을 진행했다. 다양한 시도와 포기하지 않는 의지가 중요하다는 것을 다시 한 번 실감할 수 있었다.
최종 큐레이팅 된 영화 정보 제공
앞에서 선택한 user data를 바탕으로 feature에 대한 radar plot을 제공했다. 이전에 선택한 음악과의 상관관계를 분석하였다. 영화정보, ott 정보 등을 함께 넣었고, 줄거리 정보가 있을 때와 없을 때 상황과 ...더보기(말줌임표) 기능을 구현했다. 그리고 DB와 연결된 좋아요 기능도 구현했다.
결과와 비슷한 느낌의 영화 추천
최종 선택된 영화와 가장 음악적 결이 비슷한 3개의 영화를 추가적으로 보여준다.
처음엔 더 많은 기능을 구현하려했지만, 진행될수록 여러가지 한계에 봉착했다. 프로젝트의 2/3지점이 지나는 지점에서 우리는 선택했다. 덜어낼 기능을 정하고, 완성된 서비스를 제공하자고 합의했다. 모두에게 감사했다.
페이지를 넘길 때 stepper 기능을 구현했다. 서비스페이지 내에선 page자체를 이동시키기 보다는 components 간의 이동을 택했다.
API활용에 대해 많이 배웠다. 주고 받는 과정에서 많은 것을 느꼈고, 서비스가 작동하는 원리를 이해할 수 있었다.(react 18 ver에서는 db에서 직접 꺼내오는 suspend 기능으로 data fetching 하여 획기적으로 코드수를 줄일 수 있다고한다)
광역state관리인 recoil을 사용해보았다. 지난 프로젝트에서는 useState로 돌려막기했다. 이번엔 광역으로 데이터를 관리해보며 편리한 점을 느꼈고, 잘 사용했는지는 모르겠지만 project에 api data를 받아오며 유용하게 사용할 수 있었다.
팀원들과의 소통의 중요성을 매우 크게 느꼈다.
현업 개발자들도 끊임없이 공부하고 구글링하는 것을 알게 되었다.
html와 css, react를 더 공부해야겠다고 다짐했다.
mobile first, 마크업을 하고 기능구현을 하는 과정을 복잡하게 진행하니 css 구현이 너무 어려웠다. 처음부터 목표를 가지고 markup을 해야한다고 느꼈다. 그리고 요즘은 모바일 구현이 먼저라고 하던데... 다음부턴 꼭 mobile first를 해보고 싶다. css 공부 필수. rem과 em이라도 제대로 알자
styled-components
이번 프로젝트의 css는 styled-components
를 써서 재사용성을 높여보겠다고 다짐했다. 실제로 대책없이 재사용하다보니 꼬이고 꼬이고 꼬이고 꼬이는 코드의 반복이었다. 2일간 팀원들과 함께 css 작업을 진행하였는데, 기본기가 없다는 것을 확실히 느끼게 되었다.
기능구현
일단 모르니까 못한다가 먼저 나왔다. 그만큼 아는게 별로 없었다. 얕게 있던 밑천이 금방 드러났다. 특히 JS 공부를 열심히 해야겠다고 느꼈다. react가 js기반이라는 것을 절실히 느끼게 되었다.
만족할만한 프로젝트 결과물이다.
첫째로 완성시켰다는 것, 제한된 deadline에서 우리가 조율하고 협의해 괜찮은 결과를 만들어내었다. 충분히 기분 좋은 일이다. 둘째로 나의 한계와 가능성을 보았다. 4개월차 개발자 그것도 풀스택을 맛만 본 개발자가 프론트엔드를 더 공부해보고 싶다는 생각을 가지게했다. 셋째로 좋은 동료를 만났다. 지난 4개월 온라인교육으로만 진행되다보니 나만 이렇게 못하나... 끝 없는 자신감 추락의 길을 걸었다. 프로젝트를 위해 모여 개발 입문자들의 토로를 모아보니, 모두 같은 마음이었다. elice ai 트랙을 시작하며 줄 곧 가지고 있던 고민을 내려놓을 수 있었다.
내 삶에 기록될 의미있는 시간이었고, 앞으로 조금 더 개발자의 길을 가도 괜찮겠다 생각이 들었다. 모든 순간이 완벽할 순 없다. 지금 느끼는 막연함의 늪에 바닥이 있다고 생각만 할 수 있다면 충분히 이겨낼 수 있다.
참 좋은 시간이었다.