Steam Game Recommendation Application
방대한 Steam 라이브러리 속에서 사용자가 취향에 맞는 게임을 더 쉽게 찾을 수 있도록 만든 데스크탑 추천 앱입니다. 리뷰 50건 이상의 Steam 게임 약 12,000건을 사전 수집해 H2 임베디드 DB에 탑재했고, Electron으로 패키징해 별도 서버 없이 Windows 환경에서 실행할 수 있도록 구성했습니다. 사용자는 태그 선택, Steam 프로필, 최근 플레이 기록, 자유 텍스트 입력을 통해 게임을 추천받을 수 있으며, 게임 선택 세션과 리뷰 맞추기 미니게임도 함께 제공합니다.
담당 역할
1인 개발 프로젝트로 기획, 데이터 수집, 추천 알고리즘 설계, Spring Boot API 구현, 프론트엔드 UI 제작, Electron 패키징, GitHub Releases 배포까지 전 과정을 담당했습니다. 특히 Tag Co-occurrence 기반 추천 엔진, Steam/Gemini 외부 API 연동, 캐싱, Circuit Breaker/Retry 기반 장애 대응, 데스크탑 실행 환경 구성을 중심으로 구현했습니다.

Tech Stack
아키텍처 / ERD
Electron 앱이 내장된 Spring Boot JAR를 실행하고, Spring Boot는 정적 HTML/CSS/JS UI와 REST API를 함께 제공합니다. 추천 요청은 Controller → Service → CooccurrenceService → Repository 흐름으로 처리되며, H2 DB에 저장된 게임/태그/태그 동시 출현 데이터를 조회합니다. Steam 프로필 기반 추천은 Steam Web API를, 자유 텍스트 추천은 Gemini API를 호출하고, 외부 API 장애는 timeout, retry, circuit breaker, fallback으로 격리했습니다.
주요 기능
- ✓446개 Steam 태그 간 동시 출현 빈도를 사전 계산해 78,975건의 태그 쌍 데이터를 구성했습니다. 추천 시 실제 게임 생태계에서 자주 함께 등장하는 태그 쌍을 우선 탐색해 단순 태그 매칭보다 자연스러운 추천 결과를 제공하도록 설계했습니다.
- ✓Steam Web API로 보유 게임과 최근 플레이 게임을 조회하고, 해당 게임들의 태그 빈도를 분석해 사용자의 취향 태그를 추출했습니다. 추천 결과에서는 이미 보유한 게임을 제외해 새로 플레이할 수 있는 게임이 나오도록 처리했습니다.
- ✓Gemini API로 자연어 취향 문장을 Steam 태그 배열로 변환하고, 추출된 태그를 기존 Co-occurrence 추천 파이프라인으로 연결했습니다. 동일 입력은 6시간 TTL로 캐싱해 중복 API 호출을 줄였습니다.
- ✓7라운드 동안 두 게임 중 하나를 선택하는 인터랙티브 세션과 실제 리뷰를 보고 게임을 맞추는 미니게임을 구현했습니다. 세션은 TTL 기반 인메모리 캐시로 관리해 데스크탑 앱 환경에서 별도 서버 저장소 없이 동작하도록 구성했습니다.
- ✓Spring Boot JAR와 정적 UI를 Electron으로 패키징해 Windows에서 독립 실행 가능한 앱으로 배포했습니다. API Key는 소스 코드에 직접 포함하지 않고 로컬 설정 파일 또는 환경 변수를 통해 관리하도록 구성했습니다.
트러블슈팅
- 외부 API 장애 시 앱 응답 지연 문제문제 상황Steam API 또는 Gemini API가 지연되면 추천 요청도 함께 지연되고, 데스크탑 앱 전체가 멈춘 것처럼 보일 수 있었습니다.해결 방안WebClient 호출에 5초 timeout을 설정하고, Resilience4j Retry와 Circuit Breaker를 API별로 분리 적용했습니다.장애 시 fallback을 통해 빈 결과 또는 적절한 예외를 반환하도록 구성했습니다.결과외부 API 장애가 앱 전체 장애로 전파되지 않고, 기능별로 graceful degradation이 가능해졌습니다.
- 추천 결과가 비어버리는 문제문제 상황사용자가 선택한 태그 조합이 너무 구체적이거나 추천 결과가 이미 보유 게임과 겹치면 결과가 비어 404가 발생할 수 있었습니다.해결 방안Co-occurrence 쌍 탐색 실패 시 개별 태그 탐색으로 전환하고, 태그 수 축소, 조건 완화, 기본 태그 추천으로 이어지는 다단계 폴백 전략을 적용했습니다.결과희소한 태그 조합이나 보유 게임이 많은 사용자에게도 추천 결과를 반환할 수 있게 되었습니다.
- 게임 이름 인코딩 깨짐 문제문제 상황Steam 데이터 수집 과정에서 ®, ™, © 같은 특수문자가 깨져 게임 이름이 비정상적으로 표시되었습니다.해결 방안게임명 정제 로직과 Jackson 전역 String Serializer를 통해 잘못 인코딩된 패턴을 보정했습니다.URL 필드는 별도 분기해 잘못 변환되지 않도록 처리했습니다.결과사용자에게 노출되는 게임명이 정상적으로 표시되도록 개선했고, 문자열 정제 책임을 한 곳에서 관리할 수 있게 했습니다.
성능 / 안정성
- 태그 동시 출현 데이터를 사전 계산해 추천 요청 시 실시간 조합 계산 비용을 줄였습니다.
- Gemini 태그 추출 결과를 6시간 캐싱해 동일 입력에 대한 외부 API 호출을 줄였습니다.
- Choice, Review Guess 세션은 TTL 기반 인메모리 캐시로 관리하고, 만료 데이터를 주기적으로 정리했습니다.
- Steam/Gemini API에는 timeout, retry, circuit breaker를 적용해 외부 장애 상황에서도 앱이 멈추지 않도록 구성했습니다.
보안 고려 사항
- Steam/Gemini API Key는 소스 코드에 직접 포함하지 않고 환경 변수 또는 로컬 설정 파일을 통해 관리했습니다.
- Steam ID와 요청 DTO에는 형식 검증을 적용해 잘못된 입력이 서비스 로직으로 전달되지 않도록 했습니다.
- GlobalExceptionHandler를 통해 내부 예외와 스택 트레이스가 클라이언트에 직접 노출되지 않도록 처리했습니다.
- 현재 CORS 전체 허용 설정은 로컬 데스크탑 앱 환경을 전제로 한 것이며, 서버 배포 시에는 Origin 제한이 필요합니다.
아쉬웠던 점
현재 추천 알고리즘은 태그 동시 출현 빈도 중심이라 사용자별 플레이 시간이나 선호도 가중치가 충분히 반영되지 않습니다. 다음에는 TF-IDF, 플레이 시간 가중치, 사용자 피드백을 반영해 추천 정확도를 높이고 싶습니다. Steam 데이터가 초기 수집 시점에 고정되어 있어 신규 게임과 태그 변경이 자동 반영되지 않습니다. 향후에는 주기적 데이터 업데이트 파이프라인을 추가해 데이터 최신성을 개선할 수 있습니다. 추천 로직과 폴백 전략에 대한 테스트가 부족했습니다. 다음에는 Co-occurrence 탐색, 캐시 동작, 외부 API fallback을 중심으로 테스트를 보강하고 싶습니다.
프로젝트 유형
개인 프로젝트
기간
2025.03 - 2025.07
완료
2025-07
사용 기술
9 Technologies
다른 프로젝트
CareLink
🏆 2026 GOORM DEEPDIVE HACKATHON 최우수상 외국인 환자를 위한 AI 기반 다국어 의료 커뮤니케이션 플랫폼 (증상 분석, 처방전 번역, 병원 찾기, 커뮤니티)
팀 프로젝트MSG CTF
건국대(seKUrity) · 세종대(SSG) · 명지대(MJSEC)가 함께 운영한 MSG CTF 대회 플랫폼입니다. CTFd를 사용하지 않고 Spring Boot 백엔드와 React 프론트엔드, Discord Bot을 직접 구성해 대회 운영에 필요한 회원, 문제, 점수, 관리자 기능을 구현했습니다. 이 프로젝트에서는 주로 User API와 인증 흐름을 담당했습니다.