트립로그(TripLog) 앱을 위한 REST API 서버입니다.
- 의존성 설치:
npm install
- 서버 실행:
npm start
- 브라우저에서 http://localhost:3000 접속
| API | Method | Endpoint | 설명 |
|---|---|---|---|
| 애플 로그인 | POST | /api/auth/apple |
애플 ID 토큰 검증 및 로그인/회원가입 |
| 구글 로그인 | POST | /api/auth/google |
구글 ID 토큰 검증 및 로그인/회원가입 |
| 로그아웃 | POST | /api/auth/logout |
로그아웃 및 토큰 무효화 |
| 토큰 갱신 | POST | /api/auth/refresh |
액세스 토큰 갱신 |
| 회원 탈퇴 | DELETE | /api/auth/withdraw |
회원 탈퇴 (SNS 연동 해제 포함) |
| API | Method | Endpoint | 설명 |
|---|---|---|---|
| 내 정보 조회 | GET | /api/users/me |
로그인 사용자 정보 |
| 내 정보 수정 | PUT | /api/users/me |
프로필 수정 |
| API | Method | Endpoint | 설명 |
|---|---|---|---|
| 여행 목록 조회 | GET | /api/trips |
내 여행 전체 목록 |
| 여행 상세 조회 | GET | /api/trips/:tripId |
특정 여행 상세 |
| 여행 생성 | POST | /api/trips |
새 여행 추가 |
| 여행 수정 | PUT | /api/trips/:tripId |
여행 정보 수정 |
| 여행 삭제 | DELETE | /api/trips/:tripId |
여행 삭제 |
| API | Method | Endpoint | 설명 |
|---|---|---|---|
| 장소 목록 조회 | GET | /api/trips/:tripId/places |
여행 내 장소 목록 |
| 장소 상세 조회 | GET | /api/places/:placeId |
특정 장소 상세 |
| 장소 추가 | POST | /api/trips/:tripId/places |
여행에 장소 추가 |
| 장소 수정 | PUT | /api/places/:placeId |
장소 정보 수정 |
| 장소 삭제 | DELETE | /api/places/:placeId |
장소 삭제 |
| 장소 검색 | GET | /api/places/search |
지도 기반 장소 검색 |
| API | Method | Endpoint | 설명 |
|---|---|---|---|
| 사진 목록 조회 | GET | /api/places/:placeId/photos |
장소별 사진 목록 |
| 사진 상세 조회 | GET | /api/photos/:photoId |
특정 사진 상세 |
| 사진 업로드 | POST | /api/places/:placeId/photos |
사진 업로드 |
| 사진 삭제 | DELETE | /api/photos/:photoId |
사진 삭제 |
| 대표 이미지 설정 | PUT | /api/trips/:tripId/cover |
여행 대표 이미지 지정 |
| API | Method | Endpoint | 설명 |
|---|---|---|---|
| 게시물 목록 조회 | GET | /api/posts |
피드 조회 (페이징 지원) |
| 게시물 상세 조회 | GET | /api/posts/:postId |
특정 게시물 상세 |
| 게시물 생성 | POST | /api/posts |
게시물 작성 (이미지 다중 업로드 & 메타데이터 지원) |
| 게시물 수정 | PUT | /api/posts/:postId |
게시물 수정 |
| 게시물 삭제 | DELETE | /api/posts/:postId |
게시물 삭제 |
| 게시물 좋아요 | POST | /api/posts/:postId/like |
게시물 좋아요 추가/제거 (토글) |
| 댓글 목록 조회 | GET | /api/posts/:postId/comments |
게시물 댓글 조회 |
| 댓글 작성 | POST | /api/posts/:postId/comments |
댓글 작성 |
| 댓글 수정 | PUT | /api/comments/:commentId |
댓글 수정 |
| 댓글 삭제 | DELETE | /api/comments/:commentId |
댓글 삭제 |
| 댓글 좋아요 | POST | /api/comments/:commentId/like |
댓글 좋아요 추가/제거 (토글) |
게시물 생성 예시:
# 기본 예시
curl -X POST http://localhost:3000/api/posts \
-H "Authorization: Bearer {token}" \
-F "content=부산 여행 너무 좋았어요!" \
-F "images=@photo1.jpg" \
-F "images=@photo2.jpg" \
-F "tags=부산,여행,맛집" \
-F "visibility=public"
# 이미지 메타데이터 포함 (각 사진의 위치, 촬영 시간 등)
curl -X POST http://localhost:3000/api/posts \
-H "Authorization: Bearer {token}" \
-F "content=부산 여행" \
-F "images=@photo1.jpg" \
-F "images=@photo2.jpg" \
-F "imageMeta=[{\"latitude\":37.27652,\"longitude\":127.00852,\"locationName\":\"부산 해운대\",\"capturedAt\":\"2026-02-05T12:00:00Z\"},{\"latitude\":37.27700,\"longitude\":127.00900,\"locationName\":\"부산 광안리\"}]" \
-F "tags=부산,여행,맛집"이미지 메타데이터 구조: 각 이미지는 다음 메타데이터를 포함할 수 있습니다:
{
"latitude": 37.27652, // 위도 (필수)
"longitude": 127.00852, // 경도 (필수)
"locationName": "부산 해운대", // 위치 이름 (선택)
"address": "부산 수영구 해운대로...", // 주소 (선택)
"capturedAt": "2026-02-05T12:00:00Z", // 촬영 시간 (선택)
"description": "해운대 비치" // 이미지 설명 (선택)
}지원 이미지 형식: JPEG, JPG, PNG, GIF, WebP (최대 10개, 파일당 10MB 이하)
이미지 업로드 기능:
- ✅ 다중 이미지 업로드 (최대 10개)
- ✅ 자동 썸네일 생성 (Sharp를 이용한 400x400 JPG 생성)
- ✅ 이미지별 메타데이터 저장 (위치, 촬영시간, 설명)
- ✅ 자동 파일명 관리 및 서버 저장
- 📁 저장 경로:
/uploads/posts/(원본),/uploads/thumbnails/(썸네일)
웹 테스트 페이지: http://localhost:3000/test-image-upload
썸네일 자동 생성:
- 업로드된 모든 이미지에 대해 400x400 JPG 썸네일 자동 생성
- Sharp 라이브러리를 사용하여 효율적인 이미지 처리
- 생성 실패 시 원본 이미지 URL 반환 (폴백)
- 썸네일은
thumbnail필드에 저장됨
응답 예시:
{
"success": true,
"data": {
"_id": "123abc",
"images": [
{
"_id": "img001",
"url": "/uploads/posts/photo_12345.jpg",
"thumbnail": "/uploads/thumbnails/photo_12345_thumb.jpg",
"order": 0,
"location": {
"name": "부산 해운대",
"address": "부산 수영구 해운대로...",
"coordinates": {
"latitude": 37.27652,
"longitude": 127.00852
}
},
"capturedAt": "2026-02-05T12:00:00Z",
"description": "해운대 비치"
}
]
}
}
---
### ⭐ 추천 여행 (Recommendation)
| API | Method | Endpoint | 설명 |
|-----|--------|----------|------|
| 추천 여행 목록 | GET | `/api/recommendations` | 추천 여행지 목록 (DB/공공 API, 페이징 지원) |
| 추천 여행 상세 | GET | `/api/recommendations/:id` | 추천 여행 상세 조회 |
| 관광정보 검색 | GET | `/api/recommendations/search` | 한국관광공사 공공 API 키워드 검색 |
---
### 🔖 북마크 (Bookmark)
| API | Method | Endpoint | 설명 |
|-----|--------|----------|------|
| 북마크 토글 | POST | `/api/bookmarks/toggle` | 북마크 추가/제거 (토글) |
| 북마크 목록 조회 | GET | `/api/bookmarks` | 내 북마크 목록 (페이징 지원) |
| 북마크 상태 확인 | GET | `/api/bookmarks/check/:id` | 특정 여행지 북마크 여부 확인 |
| 모든 북마크 삭제 | DELETE | `/api/bookmarks` | 북마크 일괄 삭제 |
**쿼리 파라미터**:
- `category`: 카테고리 필터 (관광지, 문화시설, 축제공연행사, 여행코스, 레포츠, 숙박, 쇼핑, 산, 바다, 도시)
- `region`: 지역 (공공 API 사용 시)
- `usePublicApi`: true/false (기본값: false - DB 데이터 사용)
- `page`: 페이지 번호 (기본값: 1)
- `pageSize`: 한 페이지 항목 수 (기본값: 20, 최대: 100)
**예시**:
```
# 제주의 관광지 추천 (공공 API, 1페이지, 페이지당 10개)
GET /api/recommendations?region=제주&usePublicApi=true&category=관광지&page=1&pageSize=10
# DB 추천 정보 (산 카테고리, 2페이지)
GET /api/recommendations?category=산&page=2&pageSize=20
# 키워드 검색 (페이징 지원)
GET /api/recommendations/search?keyword=서울&page=1&pageSize=20
```
---
### 🔖 북마크 (Bookmark)
| API | Method | Endpoint | 설명 |
|-----|--------|----------|------|
| 북마크 토글 | POST | `/api/bookmarks/toggle` | 북마크 추가/제거 (토글) |
| 북마크 목록 조회 | GET | `/api/bookmarks` | 내 북마크 목록 (페이징 지원) |
| 북마크 상태 확인 | GET | `/api/bookmarks/check/:id` | 특정 여행지 북마크 여부 확인 |
| 모든 북마크 삭제 | DELETE | `/api/bookmarks` | 북마크 일괄 삭제 |
**쿼리 파라미터** (목록 조회):
- `page`: 페이지 번호 (기본값: 1)
- `pageSize`: 한 페이지 항목 수 (기본값: 20, 최대: 100)
- `sortBy`: 정렬 기준 (-createdAt, createdAt, title, -title)
**예시**:
```bash
# 북마크 추가/제거
POST /api/bookmarks/toggle
Headers: Authorization: Bearer {token}
Body: {"recommendationId": "2850913"}
# 북마크 목록 조회 (페이징)
GET /api/bookmarks?page=1&pageSize=10
Headers: Authorization: Bearer {token}
# 북마크 상태 확인
GET /api/bookmarks/check/2850913
Headers: Authorization: Bearer {token}
```
**응답 예시**:
```json
// 북마크 토글 - 추가 시
{
"message": "북마크가 추가되었습니다",
"isBookmarked": true,
"bookmarkCount": 5
}
// 북마크 목록 조회
{
"pagination": {
"page": 1,
"pageSize": 20,
"total": 5,
"totalPages": 1
},
"count": 5,
"data": ["2850913", "2850914", "69833ce1819d809ddb3a869b"]
}
```
---
### ⚙️ 설정 (Settings)
| API | Method | Endpoint | 설명 |
|-----|--------|----------|------|
| 설정 조회 | GET | `/api/settings` | 사용자 설정 조회 |
| 설정 수정 | PUT | `/api/settings` | 알림, 테마 등 수정 |
---
## 공공 API 통합
### 한국관광공사 관광정보 서비스
TripLog는 한국관광공사의 공공 API를 통합하여 실시간 국내 관광정보를 제공합니다.
**Base URL**: `https://apis.data.go.kr/B551011/KorService2`
**주요 기능**:
- 🗺️ **지역기반 관광정보 조회** (`areaBasedList2`)
- 지역코드별 관광지, 문화시설, 축제, 숙박 등 조회
- 카테고리 필터링 지원
- 페이징 처리 (최대 100개/페이지)
- 🔍 **키워드 검색** (`searchKeyword2`)
- 전국 관광정보 검색
- 페이징 지원
- 📋 **상세정보 조회** (`detailCommon2`, `detailImage2`)
- 관광지 상세 정보 및 이미지 조회
**지원 지역** (17개):
서울, 인천, 대전, 대구, 광주, 부산, 울산, 세종, 경기, 강원, 충북, 충남, 전북, 전남, 경북, 경남, 제주
**카테고리** (공공 API):
- 관광지 (12)
- 문화시설 (14)
- 축제공연행사 (15)
- 여행코스 (25)
- 레포츠 (28)
- 숙박 (32)
- 쇼핑 (38)
**환경변수 설정**:
```
# .env 파일
TOUR_API_KEY=your_api_key_here
```
---
## 페이징 처리
모든 목록 조회 API에서 페이징을 지원합니다.
**응답 구조**:
```json
{
"source": "database",
"pagination": {
"page": 1, // 현재 페이지
"pageSize": 20, // 페이지 크기
"total": 1904, // 전체 항목 수
"totalPages": 96 // 전체 페이지 수
},
"count": 20, // 현재 페이지 항목 수
"category": "산",
"data": [...] // 데이터 배열
}
```
**페이징 파라미터**:
- `page`: 1부터 시작 (기본값: 1)
- `pageSize`: 1~100 사이의 값 (기본값: 20)
---
## 인증 방식
### 구글 SNS 로그인 설정
**환경변수**:
```
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REDIRECT_URI=your_google_redirect_uri
```
**참고**: 여러 플랫폼(웹/Android/iOS) 클라이언트 ID를 사용할 경우 `GOOGLE_CLIENT_ID`에 콤마(,)로 구분해 입력할 수 있습니다.
**요청 예시**:
```json
// POST /api/auth/google (idToken 방식)
{
"idToken": "구글에서 받은 ID 토큰"
}
// POST /api/auth/google (authorizationCode 방식)
{
"authorizationCode": "구글 OAuth 인가 코드"
}
```
### 요청 예시
```json
// POST /api/auth/apple
{
"idToken": "애플에서 받은 ID 토큰",
"authorizationCode": "인가 코드 (선택)"
}
// POST /api/auth/google
{
"idToken": "구글에서 받은 ID 토큰"
}
```
### 응답 예시
```json
{
"accessToken": "JWT 액세스 토큰",
"refreshToken": "JWT 리프레시 토큰",
"user": {
"id": "user_123",
"email": "user@example.com",
"name": "홍길동",
"provider": "apple"
},
"isNewUser": true
}
```
### 인증 헤더
모든 인증이 필요한 API 요청 시:
```
Authorization: Bearer {accessToken}
```
---
## Google OAuth 설정
### Google Cloud Console 설정
1. [Google Cloud Console](https://console.cloud.google.com) 접속
2. 새 프로젝트 생성 또는 기존 프로젝트 선택
3. **API 및 서비스** → **사용자 인증 정보**
4. **사용자 인증 정보 만들기** → **OAuth 2.0 클라이언트 ID**
5. 애플리케이션 유형: **웹 애플리케이션**
6. **승인된 자바스크립트 원본** 추가:
- `http://localhost:3000`
7. **승인된 리디렉션 URI** 추가:
- `http://localhost:3000/api/auth/google/callback`
8. 클라이언트 ID와 클라이언트 비밀번호 복사
### .env 설정
```env
GOOGLE_CLIENT_ID=your_client_id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your_client_secret
GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/google/callback
```
### Google 로그인 흐름
**1. ID Token 방식** (권장):
```bash
POST /api/auth/google
Content-Type: application/json
{
"idToken": "eyJhbGciOiJSUzI1NiIs..."
}
```
**2. Authorization Code 방식** (웹 테스트):
- 접속: http://localhost:3000/test-google-login
- "Google 계정으로 직접 로그인" 버튼 클릭
- 로그인 후 자동으로 콜백 처리
### 응답 형식
```json
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "user_123",
"email": "user@example.com",
"name": "John Doe",
"provider": "google"
},
"isNewUser": true
}
```
---
## 웹 테스트 페이지
모든 기능을 브라우저에서 테스트할 수 있습니다:
| 페이지 | URL | 용도 |
|--------|-----|------|
| Google 로그인 | http://localhost:3000/test-google-login | Google OAuth 테스트 |
| Apple 로그인 | http://localhost:3000/test-apple-login | Apple OAuth 테스트 (설정 필요) |
| 이미지 업로드 | http://localhost:3000/test-image-upload | 이미지 업로드 및 메타데이터 테스트 |
---
## 샘플 데이터 추가
데이터베이스에 샘플 추천여행지를 추가하려면:
```bash
npm run seed:recommendations
```
이 명령어는 5개의 샘플 추천여행지를 DB에 추가합니다:
- 제주 한라산 등산 (산)
- 강릉 정동진 해변 일출 (바다)
- 지리산 천왕봉 트레킹 (산)
- 서울 남산 야경 (도시)
- 부산 광안리 해수욕장 (바다)
---
## API 문서
### Swagger UI
서버 실행 후 http://localhost:3000/api-docs 에서 모든 API 문서와 테스트 기능을 사용할 수 있습니다.
---
## 기술 스택
- **Runtime**: Node.js
- **Framework**: Express.js
- **Database**: MongoDB (Mongoose ODM)
- **Authentication**: JWT + Apple/Google OAuth2
- **API Documentation**: Swagger/OpenAPI 3.0
- **HTTP Client**: Axios
- **Security**: Helmet, CORS, Morgan
---
## 구조
```
src/
├── config/ # 설정
│ ├── index.js # 환경변수 관리
│ ├── database.js # MongoDB 연결
│ └── swagger.js # Swagger 설정
├── controllers/ # 요청 처리 로직
├── models/ # Mongoose 스키마
├── routes/ # API 라우트
├── middlewares/ # 미들웨어
├── services/ # 외부 API 호출 (공공 API 등)
└── seeds/ # 데이터 시드 스크립트
```
---
**총 API 개수: 30개** (북마크 4개 포함)
**마지막 업데이트**: 2026.02.05
- ✅ 한국관광공사 공공 API 통합
- ✅ 카테고리 필터링 (DB & 공공 API)
- ✅ 페이징 처리 (모든 목록 조회 API)
- ✅ 북마크 기능 (추가/제거/목록/일괄삭제)
- ✅ Swagger 문서 업데이트
- ✅ 게시물 이미지 업로드 기능 (다중 파일 지원)