
프롬프트 기반으로 노래 추천 혹은 가사를 생성해주는 애플리케이션을 기획한 바 있다. 기획부터 시작하여 로컬에서 리팩토링을 포함한 개발이 완성되기까지 약 한 달 정도의 시간이 소요됐다.
올해 초 개인 프로젝트로 진행했던 노래 추천 애플리케이션을 리팩토링하는 작업이었기 때문에 큰 어려움 없이 진행할 수 있을 거라고 생각하고 기획부터 배포까지 한 달을 잡았다.
하지만 현실은 배포는 시작도 못했다...😱
작업 속도가 나지 않았던 문제는 다른 기술 스택을 가진 개발자와의 소통에 어려움을 겪은 것에서 대개 파생되었다.
그로 인해 작업 도중에 메인 로직이 변경되면서 ERD, 디렉토리 구조를 대폭 수정해야 하는 일이 발생했다.
팀원이 개발에만 집중할 수 있는 상황이 아니었던 것과 나 또한 취업박람회나 별도의 스터디를 병행했던 점이 작업 속도가 더뎠던 이유 중 하나다.
비록 계획한 시간 안에 목표를 달성하는 데는 실패했지만, 프로젝트를 진행하며 얻은 교훈과 기술적인 성장은 무엇보다 값졌다.
| 항목 | 내용 |
|---|---|
| 작업 기간 | 2024.01 ~ 2024.02 |
| 작업 개요 | 프롬프팅을 기반으로 한 음악 추천 웹 애플리케이션 |
| 참여 인원 | 서버 개발자 1명( = 나) |
| 사용 언어 및 개발 환경 | JavaScript, Python, FastAPI, Pandas |
| 담당 역할 | Melon 실시간 Top100 노래 크롤링, 데이터 분석, OpenAI API를 이용해 GPT-3.5 모델로 노래 추천 알고리즘 적용 |
리팩토링 이전 노래 추천 기능은 아래와 같은 한계를 가지고 있었다.
user_input을 임베딩하여 코사인 유사도를 구한 후 모델에 주입 포스트맨(Postman)을 사용 | 항목 | 내용 |
|---|---|
| 작업 기간 | 2024.10 ~ 2024.11 |
| 작업 개요 | 프롬프팅을 기반으로 노래 추천 및 작사 생성 기능을 포함한 음악 추천 웹 애플리케이션 |
| 참여 인원 | 스프링 서버 개발자 1명, 모델 서버 개발자 1명 |
| 사용 언어 및 개발 환경 | Spring Boot, React, FastAPI, PostgreSQL, Redis, Docker |
| 담당 역할 | 웹(프론트&서버) 전체 기능 담당, 전체 애플리케이션 리팩토링, Spring Boot 기반 API 개발, DB 설계 및 최적화 등 |
form-data 형식으로 POST 요청을 보냄.Spring Boot에서 로그인 요청을 처리하고 JWT를 생성하여 HttpOnly 설정된 쿠키에 저장.HttpOnly 설정으로 인해 JavaScript에서 쿠키에 접근할 수 없으므로 XSS 공격을 예방하고, 프론트엔드는 Request를 보낼 때 credentials: 'include'로 쿠키를 포함하여 JWT를 확인하고 검증함SameSite 설정으로 CSRF 공격을 방지함Spring Boot에서 지정한 whiteListUris 경로 외에 API Call 발생 시 React가 /verify 경로로 POST 요청을 보냄Spring Boot는 React로부터 받은 요청을 기반으로 JWT를 검증하여 인증 상태를 확인.Spring Security의 Principal 객체를 활용해 2중 인증을 수행하여 보안 강화함.Spring Boot가 다음 작업을 수행함. Max-Age=0 쿠키를 발급하여 쿠키의 유효기간을 즉시 만료. React는 로그아웃 후 LocalStorage 등 클라이언트 저장소를 초기화하여 브라우저에 남아있는 인증 정보를 제거. 
리팩토링 후 UI와 UX를 대폭 개선하여 React 기반 프론트엔드를 구축했다.
1개 ~ 3개React에서 쿠키 + String이 담긴 Request를 Springboot에 요청Springboot에서 FastAPI로 노래 추천 POST 요청 FastAPI에서 요청 받은 Request를 임베딩 후, 코사인 유사도로 유사한 곡 1~3개를 선별한 후 Springboot로 String 값이 담긴 Response 보냄OpenAI API를 통해 텍스트를 임베딩하고, Redis에서 코사인 유사도를 계산하여 곡 데이터를 검색Springboot가 String을 객체로 역직렬화시킨 후, React 로 쿠키 + Response 보냄
1개React에서 쿠키 + String이 담긴 Request를 Springboot에 요청Springboot에서 FastAPI로 작사 추천 POST 요청 FastAPI에서 요청 받은 Request를 임베딩 후, 코사인 유사도를 계산하여 유사한 가사를 생성한 뒤, Springboot로 String 값이 담긴 Response 보냄OpenAI API를 사용해 일기 내용을 임베딩하고, Redis에서 유사한 가사를 검색GPT 모델을 활용해 새로운 가사를 생성Springboot에 반환Springboot가 String을 객체로 역직렬화시킨 후, React 로 쿠키 + Response 보냄
React에서 북마크 등록 요청을 Spring Boot로 전달하며, Spring Boot는 북마크 데이터를 처리하고 데이터베이스에 저장.
React에서 삭제 요청을 Spring Boot로 전달.Spring Boot는 해당 데이터를 삭제하고 성공 여부를 반환.
React에서 Spring Boot로 북마크 목록 조회 요청을 전송.Spring Boot가 저장된 북마크 데이터를 JSON 형식으로 반환하며, React는 이를 마이페이지 UI에 렌더링.
React에서 특정 북마크 ID를 기반으로 노래 추천 북마크 데이터를 Spring Boot로 요청.Spring Boot는 해당 데이터를 조회하여 반환하며, React는 이를 상세 페이지에 표시.
React에서 특정 북마크 ID를 기반으로 작사 추천 북마크 데이터를 Spring Boot로 요청.Spring Boot는 데이터를 조회하여 반환하고, React는 이를 상세 페이지에 텍스트 기반으로 표시.
요청 문자열 길이가 길어지면 Read Timeout등이 발생할 수 있다. 이를 동적 타임아웃을 설정하고 Spring Retry를 활용한 재시도 로직을 구현했지만, 클라이언트 입장에서는 연결만 끊기지 않을 뿐 하염없이 기다리게 된다. 따라서 로딩 상태를 시각적으로 표현할 필요가 있었다.
입력창과 버튼에 "처리 중..." 문구를 표시.토스트 메시지나 모달은 ESC 키나 컴포넌트 외부 클릭으로 닫을 수 있도록 구현.DDD(Domain-Driven Design) 원칙을 기반으로 도메인 중심 설계를 도입하여 비즈니스 로직과 데이터 처리 로직을 명확히 분리함.Notion과 Git Issue 템플릿을 통한 문서화 경험. 이번 프로젝트를 통해 가장 크게 느낀 것은, 협업에서 소통의 중요성이다. 서로 다른 기술 스택을 사용하는 개발자 간에는 기술적 용어와 문서화된 내용만으로 모든 상황을 해결하기 어렵다는 것을 체감했다.
특히, 디렉토리 구조와 ERD 변경처럼 프로젝트의 근본적인 부분을 수정해야 할 때, 초반의 소통 미흡이 큰 영향을 미쳤다.
이후 디스코드 화면 공유와 같은 직접적인 커뮤니케이션 방법을 통해 문제를 해결했던 경험은 앞으로의 협업에서 매우 유용한 교훈이 될 것이다.
애초에 한 달이라는 타이트한 일정으로 기획부터 배포까지 완성하는 것은 도전적인 목표였다.
하지만 예기치 못한 변수들로 인해 일정이 지연되면서, 계획을 수정하고 핵심 기능에 우선순위를 두는 유연함이 필요하다는 것을 다시 한번 느꼈다.
모든 작업을 한 번에 완벽하게 처리하기보다는, 진행 가능한 부분부터 차근차근 완성해나가는 것이 더 생산적인 결과를 만들어낸다는 점을 알게 되었다.
이번 프로젝트는 단순히 기술을 배우고 적용하는 것을 넘어, 시스템 전체를 설계하고 최적화하며 사용자 경험까지 고려하는 과정이었다.
특히, 프론트엔드와 백엔드를 모두 담당하면서 데이터의 흐름과 API 설계, 그리고 사용자 인터페이스 간의 상호작용을 깊이 이해할 수 있었다.
특히, 프론트엔드 개발을 경험하며 얻은 자신감은 이후 프로젝트에서도 협업 혹은 프론트엔드 개발을 맡아야 하는 상황에서 큰 도움이 될 것이다.
배포를 완료하지 못했다는 점은 아쉬움으로 남지만, 이번 프로젝트는 완벽보다는 학습과 성장에 집중하는 과정이었다.
웹을 온전히 도맡아 작업하면서 그동안 궁금했던 DDD 등의 방법론, 그리고 Spring Security, Spring Retry, WebClient같은 새로운 기술 스택을 성공적으로 적용한 경험은 목표 달성과 버금가는 가치가 있다고 생각한다.
이번 프로젝트를 진행하며 좋은 개발자란 무엇인가에 대해 깊이 고민하게 되었다.
마감 기한, 요구사항, 그리고 좋은 코드라는 세 가지 요소는 항상 개발자에게 주어진 중요한 과제다.
이번 프로젝트를 통해 깨달은 점은, 이 세 가지 요소를 균형 있게 맞추고, 상황에 따라 각 요소를 최대로 끌어올리는 것이 좋은 개발자의 역할이라는 것이다.
이번 프로젝트에서 목표를 완벽히 달성하지 못했지만, 이 과정을 통해 어떤 상황에서도 현실적이고 최선의 선택을 할 줄 아는 개발자로 성장할 수 있었다고 믿는다.
👍