"혼자 가는 여행도 좋지만, 함께할 때 더 빛나는 순간들을 위해"
WeGo는 여행 일정 수립부터 동행 구하기, 그리고 여행 중 실시간 소통까지 끊김 없는 경험을 제공하는 여행 올인원 플랫폼의 Backend Server입니다.
단순한 기능 구현을 넘어, 사용자 경험(UX)과 시스템 성능/안정성을 고려하여 기술을 선정하고 구현했습니다.
- Problem: 여행 정보는 날짜, 위치, 테마, 참가자 수 등 다양한 필터링 조건이 동적으로 조합되어야 했습니다. 표준 JPA API만으로는 동적 쿼리 작성이 어렵고 가독성이 떨어지는 문제가 있었습니다.
- Solution: QueryDSL 5.0을 도입하여 타입 세이프(Type-Safe)한 동적 쿼리를 구현했습니다. 이를 통해 컴파일 시점에 문법 오류를 잡고, 복잡한 검색 로직을 직관적인 코드로 작성하여 유지보수성을 대폭 향상시켰습니다.
- Problem: 여행 중 동행자들과의 즉각적인 의사소통은 필수적입니다. 일반적인 HTTP 요청 방식(Polling)은 서버 부하가 높고 실시간성을 보장하기 어려웠습니다.
- Solution: WebSocket과 STOMP 프로토콜을 활용하여 실시간 채팅 기능을 구축했습니다. 채팅방 구독(Subscribe) 및 메시지 발행(Publish) 모델을 통해 낮은 지연 시간으로 다자간 대화를 지원하며, 여행 그룹 간의 긴밀한 연결을 도왔습니다.
- Problem: 회원가입 시 이메일 인증 코드와 같은 임시 데이터의 수명 주기(TTL) 관리와 빈번한 조회 요청이 DB에 부하를 줄 수 있었습니다.
- Solution: 인메모리 DB인 Redis를 도입했습니다. 인증 코드의 만료 시간을 TTL 기능으로 자동 관리하고, 빠른 I/O 속도를 통해 인증 프로세스의 지연을 최소화하여 사용자 경험을 개선했습니다.
- Problem: Docker Daemon이 없는 CI 환경에서 이미지를 빌드하거나, 레이어 캐싱 효율을 높여 빌드 속도를 개선할 필요가 있었습니다.
- Solution: Google의 Jib 플러그인을 사용하여 Dockerfile 없이 자바 애플리케이션을 최적화된 컨테이너 이미지로 빌드했습니다. 이를 통해 빌드 속도를 단축하고 배포 파이프라인(GitHub Actions 등)을 경량화했습니다.
RESTful API 원칙을 준수하여 설계를 진행했으며, 주요 리소스는 다음과 같습니다.
| Domain | Method | URI | Description |
|---|---|---|---|
| Auth | POST |
/api/v1/auth/login |
사용자 로그인 (JWT 발급) |
| User | POST |
/api/v1/users |
회원가입 |
| Travel | GET |
/api/v1/travels |
여행지 검색 및 목록 조회 (QueryDSL) |
| Travel | POST |
/api/v1/travels |
새로운 여행 생성 |
| Review | POST |
/api/v1/reviews |
여행 리뷰 작성 |
| Chat | WS |
/ws-stomp |
웹소켓 연결 엔드포인트 |
상세한 API 명세는 프로젝트 실행 후
/swagger-ui/index.html에서 확인 가능합니다.
Layered Architecture를 기반으로 도메인(Domain)을 중심으로 비즈니스 로직을 격리하여 응집도를 높였습니다.
graph TD
Client["Client (Web/App)"] -->|HTTPS| ALB[Load Balancer]
ALB -->|API Request| WAS[Spring Boot Server]
subgraph "Backend Server"
WAS -->|Auth/Cache| Redis
WAS -->|Data Persistence| DB[(MariaDB/MySQL)]
WAS -->|Image Storage| S3[AWS S3]
WAS -->|Mail Send| SMTP[Google SMTP]
end
src/main/java/potatoes/server
├── auth # 인증/인가 (JWT, Security)
├── chat # 실시간 채팅 (WebSocket, Stomp)
├── review # 여행지 리뷰 및 평점
├── travel # 여행 일정, 동행 관리 (Core Domain)
├── user # 사용자 정보 관리
└── infra # 외부 인프라 연동 (S3, Redis, Mail config)
주요 도메인 간의 관계를 설계하여 데이터 무결성을 보장했습니다.
erDiagram
Users ||--o{ TravelUser : participates
Users ||--o{ Review : writes
Users ||--o{ ReviewLike : likes
Users ||--o{ ChatUser : joins
Travel ||--o{ TravelUser : includes
Travel ||--o{ TravelPlan : has_plans
Travel ||--o{ Chat : has_chatroom
Review ||--o{ ReviewImage : contains
Review ||--o{ ReviewLike : received_likes
Chat ||--o{ ChatUser : has_members
Chat ||--o{ ChatMessage : contains_messages
Users {
Long id PK
String email
String nickname
String provider
}
Travel {
Long id PK
String title
LocalDateTime startDate
LocalDateTime endDate
Int maxParticipants
}
Review {
Long id PK
String content
Double rating
}
- JDK 21
- Redis (Local or Container)
- Database (H2/MariaDB)
# Clone the repository
git clone https://github.com/Team-Talking-Potatoes/WeGo_BE.git
# Move to the directory
cd WeGo_BE
# Build with Gradle (without tests for faster setup)
./gradlew clean build -x test
# Run the application
java -jar build/libs/WeGo_BE-0.0.1-SNAPSHOT.jarDeveloped by Team Talking Potatoes