BookPick MVP ๋ฒ์ ์ ๋ฐฑ์๋ API ์๋ฒ์ ๋๋ค. AI ๊ธฐ๋ฐ ๋์ ํ๋ ์ด์ ๋ฐ ์ถ์ฒ ์๋น์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Java 17
- Spring Boot 3.5.6
- Spring Security 6
- Spring Data JPA
- MySQL 8.0+
- JWT (JJWT 0.12.6) - ์ฌ์ฉ์ ์ธ์ฆ/์ธ๊ฐ
- SpringDoc OpenAPI 2.8.11 - API ๋ฌธ์ ์๋ํ (Swagger UI)
- Lombok - ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋ ์ ๊ฑฐ
- Gemini AI - AI ๊ธฐ๋ฐ ๋์ ์ถ์ฒ ๋ฐ ํ๋ ์ด์
- Gradle - ๋น๋ ๋๊ตฌ
- Docker - ์ปจํ ์ด๋ํ ๋ฐ ๋ฐฐํฌ
- JWT ๊ธฐ๋ฐ ์ธ์ฆ/์ธ๊ฐ ์์คํ
- ํ์๊ฐ์ , ๋ก๊ทธ์ธ, ๋ก๊ทธ์์
- Access Token / Refresh Token ๊ด๋ฆฌ
- AI ๊ธฐ๋ฐ ๋์ ์ถ์ฒ (Gemini API ์ฐ๋)
- ํ๋ ์ด์ ์์ฑ, ์กฐํ, ์์ , ์ญ์ (CRUD)
- ์ปค์ ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์
- ์ข์์ ๊ธฐ๋ฅ
- ๋๊ธ ์์ฑ ๋ฐ ๊ด๋ฆฌ
- ์ฌ์ฉ์ ๋ ์ ์ทจํฅ ๊ด๋ฆฌ
src/main/java/BookPick/mvp
โโโ domain
โ โโโ auth # ์ธ์ฆ/์ธ๊ฐ
โ โ โโโ controller
โ โ โโโ service
โ โ โโโ dto
โ โโโ curation # ๋์ ํ๋ ์ด์
โ โ โโโ controller
โ โ โโโ service
โ โ โโโ repository
โ โ โโโ dto
โ โ โโโ util
โ โ โโโ gemini # Gemini AI ์ฐ๋
โ โโโ comment # ๋๊ธ
โ โโโ ReadingPreference # ๋
์ ์ทจํฅ
โโโ security # Security ์ค์
โ โโโ config
โ โโโ handler
โโโ global # ๊ณตํต ์ค์ ๋ฐ ์ ํธ
src/main/resources
โโโ application.yml # ๊ณตํต ์ค์
โโโ application-local.yml # ๋ก์ปฌ ํ๊ฒฝ
โโโ application-dev.yml # ๊ฐ๋ฐ ํ๊ฒฝ
โโโ application-prod.yml # ์ด์ ํ๊ฒฝ
- JDK 17 ์ด์
- MySQL 8.0+
- Gradle 8.x (Wrapper ํฌํจ)
- ํ๊ฒฝ๋ณ์ ์ค์ ํ์ผ ์์ฑ
cp src/main/resources/.env.example src/main/resources/.env.envํ์ผ ์ค์
# Database
SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/bookpick?serverTimezone=Asia/Seoul
SPRING_DATASOURCE_USERNAME=your_username
SPRING_DATASOURCE_PASSWORD=your_password
# JWT
JWT_SECRET=your-secret-key-here
JWT_ACCESS_TOKEN_EXPIRATION=3600000
JWT_REFRESH_TOKEN_EXPIRATION=604800000
# Gemini API
GEMINI_API_KEY=your-gemini-api-key# ์์กด์ฑ ์ค์น ๋ฐ ๋น๋
./gradlew clean build
# ์ ํ๋ฆฌ์ผ์ด์
์คํ (local ํ๋กํ์ผ)
./gradlew bootRun --args='--spring.profiles.active=local'
# ๋๋
java -jar build/libs/*.jar --spring.profiles.active=local์๋ฒ๋ http://localhost:8081์์ ์คํ๋ฉ๋๋ค.
# ์ด๋ฏธ์ง ๋น๋
docker build -t bookpick-backend .
# ์ปจํ
์ด๋ ์คํ
docker run -p 8081:8081 \
-e SPRING_PROFILES_ACTIVE=dev \
--name bookpick-api \
bookpick-backend์ ํ๋ฆฌ์ผ์ด์ ์คํ ํ ์๋ ์ฃผ์์์ API ๋ฌธ์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค:
- Swagger UI:
http://localhost:8081/swagger-ui.html - OpenAPI JSON:
http://localhost:8081/v3/api-docs
POST /api/auth/signup- ํ์๊ฐ์POST /api/auth/login- ๋ก๊ทธ์ธPOST /api/auth/logout- ๋ก๊ทธ์์POST /api/auth/refresh- ํ ํฐ ๊ฐฑ์
GET /api/curations- ํ๋ ์ด์ ๋ชฉ๋ก ์กฐํ (์ปค์ ํ์ด์ง๋ค์ด์ )GET /api/curations/{id}- ํ๋ ์ด์ ์์ธ ์กฐํPOST /api/curations- ํ๋ ์ด์ ์์ฑPUT /api/curations/{id}- ํ๋ ์ด์ ์์ DELETE /api/curations/{id}- ํ๋ ์ด์ ์ญ์ POST /api/curations/{id}/like- ์ข์์ ํ ๊ธ
GET /api/preferences- ๋ ์ ์ทจํฅ ์กฐํPOST /api/preferences- ๋ ์ ์ทจํฅ ๋ฑ๋ก/์์
- Java ์ฝ๋ ์คํ์ผ์ Google Java Style Guide ์ค์
- Lombok ํ์ฉํ์ฌ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ต์ํ
# ์ ์ฒด ํ
์คํธ ์คํ
./gradlew test
# ํน์ ํ
์คํธ ์คํ
./gradlew test --tests "BookPick.mvp.domain.auth.*"main- ์ด์ ํ๊ฒฝ ๋ฐฐํฌ ๋ธ๋์นdevelop- ๊ฐ๋ฐ ํ๊ฒฝ ํตํฉ ๋ธ๋์นfeatures/*- ๊ธฐ๋ฅ ๊ฐ๋ฐ ๋ธ๋์นhotfix/*- ๊ธด๊ธ ๋ฒ๊ทธ ์์ ๋ธ๋์น
GitHub Actions๋ฅผ ํตํ ์๋ ๋ฐฐํฌ ํ์ดํ๋ผ์ธ:
develop๋ธ๋์น ํธ์ ์ ๊ฐ๋ฐ ์๋ฒ ์๋ ๋ฐฐํฌ- PR ์์ฑ ์ ๋น๋ ๋ฐ ํ ์คํธ ์๋ ์คํ
Caused by: java.sql.SQLException: Access denied for user
โ .env ํ์ผ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณ์ ์ ๋ณด๋ฅผ ํ์ธํ์ธ์.
io.jsonwebtoken.security.WeakKeyException
โ JWT_SECRET ํ๊ฒฝ๋ณ์๊ฐ ์ถฉ๋ถํ ๊ธด ํค(์ต์ 256bit)์ธ์ง ํ์ธํ์ธ์.
- ์ด์ ์์ฑ ๋๋ ํ ๋น๋ ์ด์ ํ์ธ
- Feature ๋ธ๋์น ์์ฑ (
git checkout -b features/AmazingFeature) - ๋ณ๊ฒฝ์ฌํญ ์ปค๋ฐ (
git commit -m 'Add some AmazingFeature') - ๋ธ๋์น์ ํธ์ (
git push origin features/AmazingFeature) - Pull Request ์์ฑ
This project is licensed under the MIT License.
ํ๋ก์ ํธ ๊ด๋ จ ๋ฌธ์์ฌํญ์ ์ด์๋ฅผ ํตํด ๋จ๊ฒจ์ฃผ์ธ์.