- ์๋ฌผ ์ฑ์ฅ ๊ธฐ๋ก & ์ ๋ณด ๊ณต์ ์ปค๋ฎค๋ํฐ ์๋น์ค
- ์๋น์ค ์๊ฐ
- ๊ธฐ์ ์คํ
- ํ๋ก์ ํธ ์ค์น ๋ฐ ์คํ๋ฒ
- ํ๋ก์ ํธ ๊ตฌ์กฐ
- ์ฃผ์๊ธฐ๋ฅ
- Developer
๐๏ธ ๊ฐ๋ฐ๊ธฐ๊ฐ: 2024.12.02 ~ 2025.01.07
๐ชด Botanify
- ์ฌ์ฉ์๊ฐ ์์ ์ ์๋ฌผ์ ๊ด๋ฆฌํ๊ณ , ์ฑ์ฅ ์ํ๋ฅผ ๊ธฐ๋กํ๋ฉฐ, ์๋ฌผ ๊ด๋ จ ์ ๋ณด๋ฅผ ๊ณต์ ํ ์ ์๋๋ก ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋๋ค.
- ์ ํฌ์ ๋ชฉํ๋ ์๋ฌผ ์ฑ์ฅ ์ผ์ง๋ฅผ ๊ธฐ๋กํ๊ณ ์ ๋ณด๋ฅผ ๊ณต์ ํ๋ ์ปค๋ฎค๋ํฐ ์๋น์ค๋ฅผ ์ ๊ณตํ์ฌ, ์ฌ์ฉ์๋ค์ ์์ง์ฌ ์ํ์ ๋ ์ฝ๊ณ ์ฌ๋ฏธ์๊ฒ ๋ง๋๋ ๊ฒ์ ๋๋ค.
ํ๋ก์ ํธ ์คํ ์ ์ ์๋ ํ๊ฒฝ์ด ํ์ํฉ๋๋ค.
- Java 17 ์ด์
- MySQL 8.0
- Docker
- Git
- IDE (IntelliJ, Eclipse ๋ฑ)
$git clone https://github.com/sparta-Sounganization/Botanify.git
$cd Botanifysrc/main/resources/application.yml ํ์ผ์ ์์ ํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ๊ธฐํ ์ค์ ์ ์
๋ฐ์ดํธํ์ธ์.
Details
spring:
jpa:
open-in-view: false
hibernate:
ddl-auto: none
properties:
hibernate:
show_sql: true
dialect: org.hibernate.dialect.MySQL8Dialect
jackson:
time-zone: Asia/Seoul
# mySQL Configuration
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${์ฌ์ฉ์์_mySQL_์๋ํฌ์ธํธ}
username: ${mySQL_์ฌ์ฉ์_์ด๋ฆ}
password: ${mySQL_์ฌ์ฉ์_์ํธ}
# JWT Configuration
jwt:
secret:
key: ${base64๋ก_์ํธํ๋_JWT_๋น๋ฐ_ํค}
expiration: 3600000 # 1์๊ฐ
# Google OAuth2 Configuration
security:
oauth2:
client:
registration:
google:
client-id: {Google_Client_ID}
client-secret: {Google_Client_๋น๋ฐ_ํค}
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
scope:
- profile
- email
# Redis Configuration
redis:
master:
port: 6379
host: ${์ฌ์ฉ์์ Redis ํด๋ผ์ด์ธํธ ์๋ํฌ์ธํธ}
verification:
ttl: 300 # 5๋ถ
max-attempts: 5
attempts-ttl: 3600 # 1์๊ฐ
# Email Configuration
mail:
host: smtp.gmail.com
port: 587
username: ${์๋น์ค_์ด๋ฉ์ผ_๋ฐ์ _์ด๋ฆ}
password: ${์๋น์ค_์ด๋ฉ์ผ_๋ฐ์ _์ํธ}
properties:
mail:
smtp:
auth: true
starttls:
enable: true
# ============= ^ Spring ^ ============= v External v =============
# Global Logging Configuration
logging:
level:
org.springframework.security: INFO
com.sounganization.botanify: DEBUG
org.springframework.web: DEBUG
io.github.resilience4j.circuitbreaker: DEBUG
# S3 Configuration
aws:
s3:
bucket: ${S3_๋ฒํท_์ด๋ฆ}
endpoint: ${S3_๋ฒํท_PUT_์๋ํฌ์ธํธ}
gateway: ${S3_๋ฒํท_GET_๊ฒ์ดํธ์จ์ด}
access-key: ${S3_์ธ์ฆ_ํค}
secret-key: ${S3_๋น๋ฐ_ํค}
# Monitoring Configuration
management:
endpoints:
web:
exposure:
include: circuitbreakers, health, info, prometheus
# Kakao API Configuration
kakao:
api:
key: ${kakao_์ธ์ฆ_ํค}
base-url: ${kakao_์๋ํฌ์ธํธ}
# weather API Configuration
weather:
api:
key: ${weather_์ธ์ฆ_ํค}
base-url: ${weather_์๋ํฌ์ธํธ}
# CircuitBreaker Configuration
resilience4j:
circuitbreaker:
instances:
weatherService:
slidingWindowType: COUNT_BASED # ์ฌ๋ผ์ด๋ฉ ์๋์ฐ ํ์
slidingWindowSize: 10 # ์ฌ๋ผ์ด๋ฉ ์๋์ฐ ํฌ๊ธฐ
minimumNumberOfCalls: 5 # ์ต์ ํธ์ถ ์
failureRateThreshold: 50 # ์คํจ์จ ์๊ณ๊ฐ
waitDurationInOpenState: 10s # ์ด๋ฆผ ์ํ ๋๊ธฐ ์๊ฐ (10์ด)
permittedNumberOfCallsInHalfOpenState: 3 # ๋ฐ์ด๋ฆผ ์ํ ํธ์ถ ์
slowCallRateThreshold: 100 # ๋๋ฆฐ ํธ์ถ ๋น์จ ์๊ณ๊ฐ
slowCallDurationThreshold: 3s # ๋๋ฆฐ ํธ์ถ ์ง์ ์๊ฐ (3์ด)
# plant API Configuration
nongsaro:
api:
base-url: ${nongsaro_์๋ํฌ์ธํธ}
key: ${nongsaro_์ธ์ฆ_ํค}
# OneSignal Configuration
onesignal:
app-id: ${onesignal_app_id}
rest-api-key: ${rest_api_key}Docker๋ฅผ ์ฌ์ฉํ์ฌ MySQL ๋ฐ ํ์ํ ์๋น์ค๋ฅผ ์คํํฉ๋๋ค.
$docker-compose up -dGradle์ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ๋ฅผ ๋น๋ํฉ๋๋ค.
$./gradlew build์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ๋ค์ ๋ช ๋ น์ด๋ฅผ ์คํํ์ธ์.
$./gradlew clean build๋น๋๊ฐ ์๋ฃ๋๋ฉด ์์ฑ๋ .jar ํ์ผ์ ์คํํฉ๋๋ค. ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ build > libs์ ๋ง๋ค์ด์ง jar ํ์ผ ์คํ
$java -jar Botanify-0.0.1-SNAPSHOT.jar์ ๋งํฌ์์ API ์๋ํฌ์ธํธ, ์์ฒญ/์๋ต ์์ , ๊ทธ๋ฆฌ๊ณ ํ๋ผ๋ฏธํฐ์ ๋ํ ์์ธํ ์ค๋ช ์ ํ์ธํ๊ณ Postman์์ ์ง์ ํ ์คํธํ ์ ์์ต๋๋ค.
- ์ฌ์ฉ์ ๊ด๋ฆฌ
![]() |
![]() |
|
| ๋ฉ์ธ | ํ์๊ฐ์ | ๋ก๊ทธ์ธ |
- ๋ฉ์ธ: ์ธ๊ธฐ ๊ฒ์๊ธ์ ๋ณผ ์ ์์ผ๋ฉฐ, ๋ก๊ทธ์ธ ํ์๋ ์ธ๊ธฐ๊ธ๊ณผ ์์ ์ ์๋ฌผ์ ๋ณผ ์ ์์ต๋๋ค.
- ํ์๊ฐ์ / ๋ก๊ทธ์ธ: ์ฌ์ฉ์๋ ๊ณ์ ์ ์์ฑํ๊ณ , ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค.
- ์๋ฌผ ๊ด๋ฆฌ
![]() |
![]() |
![]() |
![]() |
| ์๋ฌผ ๋ฑ๋ก ๋ฐ ๊ด๋ฆฌ | ์๋ฌผ ์ฑ์ฅ ๊ธฐ๋ก | ์๋ฌผ ์ ๋ณด ์กฐํ | ์๋ฌผ ๊ด๋ฆฌ ์๋ฆผ |
- ์๋ฌผ ๋ฑ๋ก ๋ฐ ๊ด๋ฆฌ: ์ฌ์ฉ์๊ฐ ์์ ์ ์๋ฌผ์ ๋ฑ๋กํ๊ณ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ์๋ฌผ ์ ๋ณด ์กฐํ: ๊ณ์ ๋ณ ๊ด์ ์ ๋ณด, ์ต๋ ๋ฑ์ ์๋ฌผ์ ๊ด๋ฆฌ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์๋ฌผ ์ฑ์ฅ ๊ธฐ๋ก: ์๋ฌผ์ ์ฑ์ฅ ์ผ์ง ๋ฐ ์ฌ์ง์ ๊ธฐ๋กํ ์ ์์ต๋๋ค.
- ์๋ฌผ ๊ด๋ฆฌ ์๋ฆผ: ๋ฌผ ์ฃผ๊ธฐ ์๋ฆผ, ๋น๋ฃ ์๋ฆผ ๋ฑ ์๋ฆผ์ ์ค์ ํ ์ ์์ต๋๋ค.
- ์ปค๋ฎค๋์ผ์ด์
![]() |
|
| ์ฑํ | ๊ฒ์ํ |
- ์ฑํ ๊ธฐ๋ฅ: ๋ค๋ฅธ ์ฌ์ฉ์์ 1:1 ์ํตํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- ๊ฒ์ํ ๊ธฐ๋ฅ: ์ฌ์ฉ์ ๊ฐ ์ ๋ณด ๊ณต์ ๋ฐ ์ปค๋ฎค๋ํฐ ํ๋์ ์ํ ๊ฒ์ํ์ ์ ๊ณตํฉ๋๋ค.
| ์ด๋ฆ | ์ญํ | ๋ด๋น ์ ๋ฌด | GitHub | Blog link |
|---|---|---|---|---|
| ์ฅ์ฌํ | ํ์ฅ |
๐ Diary Service - ์ฑ์ฅ ์ผ์ง CRUD ๊ธฐ๋ฅ ๊ตฌํ ๐ท Image - S3 ํ์ฉ ์ด๋ฏธ์ง ์ ๋ก๋ ๊ธฐ๋ฅ ๊ตฌํ ๐ฑ ์๋ฌผ๊ด๋ฆฌ - ์๋ฌผ OPEN API ๋ฐ์ดํฐ ์ ์ฅ ๊ธฐ๋ฅ ๊ตฌํ - ์๋ฌผ OPEN API ๋ฐ์ดํฐ ์บ์ฑ ์ฒ๋ฆฌ ๐ ํ ์คํธ ์ฝ๋ - ํ ์คํธ ์ฝ๋ ์ด์ ์์ฑ |
GitHub Link | Blog link |
| ๊น๋์ฃผ | ๋ถํ์ฅ |
๐งโ๐ป ํ์๊ฐ์
/๋ก๊ทธ์ธ - ์ด๋ฉ์ผ ํ์๊ฐ์ /๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ - Google ์์ ํ์๊ฐ์ /๋ก๊ทธ์ธ ๊ธฐ๋ฅ ๊ตฌํ - Security ์ธ์ฆ/์ธ๊ฐ ๐ฆ๏ธ ๋ ์จ ์๋น์ค - ์ง๋ API, ๋ ์จ API ์ฐ๋ ๋ฐ ๋ ์จ ์ ๋ณด ์ ๊ณต ๊ธฐ๋ฅ ๊ตฌํ ๐ณ Docker Compose - Docker Compose ํ๊ฒฝ ์ค์ ๐ CI/CD - Jenkins๋ฅผ ํ์ฉํ CI/CD ํ์ดํ๋ผ์ธ ๊ตฌ์ถ |
GitHub Link | Blog link |
| ๊ณ ์๋ผ | ํ์ |
๐ฑ ํ์ข
์๋น์ค - ํ์ข CRUD ๊ธฐ๋ฅ ๊ตฌํ ๐ ํ ์คํธ ์ฝ๋ - ํ ์คํธ ์ฝ๋ ์์ฑ ๋ฐ ์ปค๋ฒ๋ฆฌ์ง ์ฒดํฌ ๐ฆ๏ธ ๋ ์จ ์๋น์ค - ์๋/๊ฒฝ๋ ์ขํ ์์ง |
GitHub Link | Blog link |
| ๋ฆฌ์นธ์์ฑ (LIKANE SO SOUNG) | ํ์ |
โ๏ธ User Email Authentication - ํ์๊ฐ์ ์ ์ฌ์ฉ์์ ์ด๋ฉ์ผ ์ธ์ฆ ์์คํ ๊ตฌ์ถ ๐ฅ Community Service - ์ธ๊ธฐ ๊ฒ์๊ธ ์บ์ฑ ์์คํ ๊ตฌ์ถ - ๋๊ธ๊ณผ ๋ต๊ธ ๊ธฐ๋ฅ ๊ตฌํ - 1:1 ์ค์๊ฐ ์ฑํ ์์คํ ๊ตฌ์ถ ๐ฑ ์๋ฌผ ๊ด๋ฆฌ - ์๋ฌผ push ์๋ฆผ ์์คํ ๊ตฌ์ถ |
GitHub Link | Blog link |
| ์ง๋ฏผ์ง | ํ์ |
๐ฅ Community Service - ๊ฒ์ํ CRUD ๊ธฐ๋ฅ ๊ตฌํ - ๊ฒ์๊ธ ์กฐํ์ ์ด๋ทฐ์ง ๋ฐฉ์ง ๋ก์ง ์ค๊ณ ๋ฐ ๊ตฌํ ๐ฑ ์๋ฌผ๊ด๋ฆฌ - ์๋ฌผ Open API ์ฐ๋ ๋ฐ ์๋ฌผ ์ ๋ณด ๊ฒ์ ๋ฐ ์กฐํ ๊ธฐ๋ฅ ๊ตฌํ ๐ CI/CD - Jenkins๋ฅผ ํ์ฉํ CI ํ์ดํ๋ผ์ธ ๊ตฌ์ถ |
GitHub Link | Blog link |









