๊ณ ๊ฐ์ ์ํฉ์ ๋ฐ์ํ ์๋์ ์ฃผ๋ฌธ ๊ฒฐ์ ์๋ํ๋ฅผ ์ ๊ณตํ๋ ํด๋จผํฐ์น AI ์ฑ์ค๋
- ํ์ฐํคํค ๋ฐฑ์๋ ์๋ฒ๋ Spring Boot ๊ธฐ๋ฐ์ REST API ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก, ์ฑ์ค๋ ๋ฐ ๊ด๋ฆฌ์ ํ์ด์ง๋ฅผ ์ํ ์ฃผ๋ฌธ, ๊ฒฐ์ , ์๋ฆผ, ๋งค์ฅ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- SSE ๊ธฐ๋ฐ ์๋ฆผ, AWS S3 ์ด๋ฏธ์ง ์ ์ฅ, PortOne ๊ฒฐ์ API ๋ฑ์ ์ฐ๋ํ์์ผ๋ฉฐ, AWS EC2์ GitHub Actions๋ฅผ ํ์ฉํ CI/CD ์๋ ๋ฐฐํฌ ํ๊ฒฝ์ ๊ตฌ์ถํ์์ต๋๋ค.
- Language: Java 17
- Framework: Spring Boot 3.4
- Build Tool: Gradle
- Database: MySQL, AWS S3
- Payment API: PortOne ๊ฒฐ์ API
- ๋จ๋ฐฉํฅ ํต์ : Server-Sent Events (SSE)
- Deployment : AWS EC2, AWS RDS, Nginx, GitHub Actions + AWS CodeDeploy ๊ธฐ๋ฐ CI/CD
- ๋ณธ ํ๋ก์ ํธ๋ ๊ธฐ๋ฅ๋ณ ๋๋ฉ์ธ ๊ตฌ์กฐ(Domain-Driven Design)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ, ๊ฐ ๋๋ฉ์ธ์
menu,notification,order,pay,store,suggestion์ผ๋ก ๋๋ฉ๋๋ค. - ๊ฐ ๋๋ฉ์ธ ๋ด์๋ controller, service, repository, dto, entity๋ก ๋ถ๋ฆฌํ์ฌ ๊ตฌํํ์์ต๋๋ค.
โโโโmain
โ โโโโgenerated
โ โโโโjava
โ โ โโโโclovar
โ โ โโโโhowkiki
โ โ โโโโdomain
โ โ โ โโโโmenu # ๋ฉ๋ด ์กฐํ ๋ฐ ๋ฑ๋ก ๊ด๋ จ ๊ธฐ๋ฅ
โ โ โ โ โโโโcontroller
โ โ โ โ โโโโdto
โ โ โ โ โ โโโโrequestDto
โ โ โ โ โ โโโโresponseDto
โ โ โ โ โโโโentity
โ โ โ โ โโโโrepository
โ โ โ โ โโโโservice
โ โ โ โโโโnotification # ์๋ฆผ ์ ์ก ๋ฐ ์์ ๊ด๋ จ ๋ก์ง
โ โ โ โ โโโโcontroller
โ โ โ โ โโโโdto
โ โ โ โ โโโโentity
โ โ โ โ โโโโrepository
โ โ โ โ โโโโservice
โ โ โ โโโโorder # ์ฃผ๋ฌธ ์์ฑ ๋ฐ ๊ด๋ฆฌ ๊ธฐ๋ฅ
โ โ โ โ โโโโcontroller
โ โ โ โ โโโโdto
โ โ โ โ โ โโโโrequestDto
โ โ โ โ โ โโโโresponseDto
โ โ โ โ โโโโentity
โ โ โ โ โโโโrepository
โ โ โ โ โโโโservice
โ โ โ โโโโpay # ๊ฒฐ์ ์์ฒญ ๋ฐ ๊ฒ์ฆ ๊ธฐ๋ฅ (PortOne ์ฐ๋)
โ โ โ โ โโโโcontroller
โ โ โ โ โโโโdto
โ โ โ โ โโโโentity
โ โ โ โ โโโโrepository
โ โ โ โ โโโโservice
โ โ โ โโโโstore # ๋งค์ฅ ์ ๋ณด ๊ด๋ฆฌ ๊ธฐ๋ฅ
โ โ โ โ โโโโcontroller
โ โ โ โ โโโโdto
โ โ โ โ โ โโโโrequest
โ โ โ โ โ โโโโresponse
โ โ โ โ โโโโentity
โ โ โ โ โโโโrepository
โ โ โ โ โโโโservice
โ โ โ โโโโsuggestion # ์ฌ์ฉ์ ๊ฑด์์ฌํญ ์์ฑ ๋ฐ ์กฐํ ๊ธฐ๋ฅ
โ โ โ โโโโcontroller
โ โ โ โโโโdto
โ โ โ โโโโentity
โ โ โ โโโโrepository
โ โ โ โโโโservice
โ โ โโโโglobal
โ โ โโโโconfig # ์ ์ญ ์ค์ (CORS, S3, PortOne, Security ๋ฑ)
โ โ โโโโentity # ๊ณตํต ์ํฐํฐ (BaseEntity)
โ โ โโโโexception # ์ปค์คํ
์์ธ ๋ฐ ์ ์ญ ์์ธ ์ฒ๋ฆฌ ํธ๋ค๋ฌ
โ โ โโโโresponse # API ์๋ต ํฌ๋งท ํต์ผ ํด๋์ค (ApiResponse)
โ โโโโresources
โโโโtest
โโโโjava
โโโโclovar
โโโโhowkikicontroller/: REST API ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์๋ํฌ์ธํธservice/: ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌrepository/: JPA ๊ธฐ๋ฐ DB ์ ๊ทผ ๊ณ์ธตdto/: ๊ณ์ธต ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ ๊ฐ์ฒด (์์ฒญ, ์๋ต ๋ถ๋ฆฌ๋จ)entity/: ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๊ณผ ๋งคํ๋๋ ๋๋ฉ์ธ ๋ชจ๋ธglobal/config/: ์ ์ญ ์ค์ ํด๋์ค (Spring ์ค์ , S3, PortOne ๋ฑ)global/exception/: ์ปค์คํ ์์ธ ์ ์ ๋ฐ ์์ธ ์ฒ๋ฆฌ ํธ๋ค๋ฌglobal/response/: API ์๋ต ๊ตฌ์กฐ ํต์ผ์ ์ํ ๋ํผ ํด๋์ค
๊ฐ ๋๋ฉ์ธ ๋ณ ์์ธํ ๊ธฐ๋ฅ ์ค๋ช
์ ์๋์ API ๋ช
์ธ์๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.
๐ ํ์ฐํคํค - API ๋ช
์ธ์
ํ์ฐํคํค ๋ฐฑ์๋ ์๋ฒ๋ฅผ ๋ก์ปฌ์์ ์คํํ๊ธฐ ์ํ ์ ์ฐจ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
git clone https://github.com/Clover-21/Howkiki_Backend.git
cd Howkiki_Backend๋ณธ ํ๋ก์ ํธ๋ MySQL 8.0 ์ด์์ ์ฌ์ฉํ๋ฉฐ, ๊ธฐ๋ณธ์ ์ผ๋ก howkiki_db๋ผ๋ ์ด๋ฆ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด๋ฏธ ๋ก์ปฌ connection์ด ์๋ ๊ฒฝ์ฐ ์ด ๊ณผ์ ์ ๋์ด๊ฐ์
๋ ๋ฉ๋๋ค.
โ ๏ธ MySQL์ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ ๊ฐ์์ ๋ก์ปฌ ์ค์ ์ ๋ฐ๋ผ ๋ค๋ฅด๋ฏ๋ก ๋ณธ์ธ์ ํ๊ฒฝ์ ๋ง๊ฒ ์์ฑํด ์ฃผ์ธ์.
- ๐ฌ MySQL Workbench ์คํ ํ, ์ข์ธก ์๋จ์ + ๋ฒํผ(New Connection) ํด๋ฆญ
- Connection Name:
howkiki_local(์์ ๋กญ๊ฒ ์ค์ ๊ฐ๋ฅ) - Username:
root๋๋ ๋ณธ์ธ ์ค์ - Password: ์ ์ฅํด๋ ๋น๋ฐ๋ฒํธ ์ ๋ ฅ
- Test Connection ๋ฒํผ ํด๋ฆญ โ ์ฑ๊ณต ํ์ธ ํ ์ ์ฅ
- cf) ์๋ ๋ช ๋ น์ด๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์๋์ผ๋ก ์์ฑํ ์ ์์ต๋๋ค (ํ๋ก์ ํธ ์คํ์ ์๋ ์์ฑ๋๋ฏ๋ก ์ต์ ์ฌํญ):
CREATE DATABASE IF NOT EXISTS howkiki_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;- src/main/resource ์์น์ application.yml ํ์ผ์ ์๋ ํ์์ผ๋ก ์์ฑํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค, AWS S3 ์ฐ๋, ์ธ๋ถ ๊ฒฐ์ API ์ฐ๋์ ์ํ ์ ๋ณด๋ฅผ ์ค์ ํฉ๋๋ค.
- ์ฌ๊ธฐ์ [ ] ๋ถ๋ถ์ ์ค์ ๊ฐ ๋๋ ํค ๊ฐ์ ์์ฑํด์ผ ํฉ๋๋ค.
โ ๏ธ ์ด ํ์ผ์ .gitignore์ ํฌํจ๋์ด์ผ ํ๋ฉฐ, ์ ๋ ์ปค๋ฐํ๋ฉด ์๋ฉ๋๋ค.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/howkiki_db?createDatabaseIfNotExist=true&characterEncoding=UTF-8&characterSetResults=UTF-8
username: [YOUR_DB_USERNAME]
password: [YOUR_DB_PASSWORD]
jpa:
hibernate:
ddl-auto: update
generate-ddl: true
show-sql: true
servlet:
multipart:
max-file-size: 10MB # ์
๋ก๋ํ ์ ์๋ ๊ฐ๋ณ ํ์ผ ์ต๋ ํฌ๊ธฐ. ๊ธฐ๋ณธ 1MB
max-request-size: 10MB # multipart/form-data ์์ฒญ์ ์ต๋ ํ์ฉ ํฌ๊ธฐ. ๊ธฐ๋ณธ 10MB
# AWS S3
cloud:
aws:
credentials:
access-key: [AWS ACCESS KEY]
secret-key: [AWS SECRET KEY]
region:
static: ap-northeast-2 # ๋ฒํท์ ๋ฆฌ์
s3:
bucket: howkiki-img-bucket # ๋ฒํท ์ด๋ฆ
stack:
auto: false
# PortOne
portone:
api-key: [ํฌํธ์ API KEY]
api-secret: [ํฌํธ์ API SECRET]./gradlew bootRun- ์๋์ ์ํ SQL์ ํตํด ์ด๊ธฐ
Store,Menu๋ฐ์ดํฐ๋ฅผ ์ฝ์ ํ ์ ์์ต๋๋ค.
(API๋ฅผ ํตํด ์์ฑํ ์๋ ์์ผ๋ ํ ์คํธ ํธ์๋ฅผ ์ํด ์ ๊ณต) - ํ์ผ ์์น:
src/main/resources/sample-data.sql
storesํ ์ด๋ธ์ ๋งค์ฅ 1๊ฐ ์์ฑmenuํ ์ด๋ธ์ ์นดํ ๊ณ ๋ฆฌ๋ณ 25๊ฐ ๋ฉ๋ด ๋ฐ์ดํฐ ์ฝ์- ๋ชจ๋ ๋ฐ์ดํฐ์
created_at,modified_at์NOW()๋ก ์ค์
- MySQL์์
howkiki_db๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ํ sample-data.sqlํ์ผ์ ๋ถ๋ฌ์ ์คํ
- ํ์ฐํคํค ๋ฐฑ์๋ ์๋ฒ์ ์ฃผ์ ๊ธฐ๋ฅ์ REST API ํํ๋ก ์ ๊ณต๋ฉ๋๋ค.
- Postman์ ํตํด ๊ฐ ๊ธฐ๋ฅ์ ํ ์คํธํ ์ ์์ต๋๋ค.
- Postman์ ์ค์นํ๊ฑฐ๋ ์น ๋ฒ์ ์ฌ์ฉ
- ์๋ฒ ์คํ ํ
http://localhost:8080์ ๊ธฐ์ค์ผ๋ก ์์ฒญ
์๋ฒ๊ฐ ์ ์์ ์ผ๋ก ์คํ ์ค์ด์ด์ผ ํฉ๋๋ค (
./gradlew bootRun๋๋jar์คํ)
๐ ํ์ฐํคํค_API ๋ช ์ธ์(Notion)
- ๋ช ์ธ์์๋ API ์ค๋ช , ์์ฒญ URL, ์์ฒญ ๋ฐ๋, ์๋ต ํํ, ์ธ์ฆ ๋ฐฉ์ ๋ฑ์ด ํฌํจ๋์ด ์์ต๋๋ค.
- ์ฃผ๋ฌธ ์์ฑ ์์
๋ณธ ํ๋ก์ ํธ๋ ๋ค์๊ณผ ๊ฐ์ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ๋ฐ๋์์ต๋๋ค.
| ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ์ค๋ช | ์ฌ์ฉ ๋ชฉ์ |
|---|---|---|
| Spring Boot | Java ๊ธฐ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ํ๋ ์์ํฌ | ์น ์๋ฒ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์กฐ ์ ๊ณต |
| Spring Data JPA | ORM(Object-Relational Mapping) ์ง์ | Java ๊ฐ์ฒด โ DB ํ ์ด๋ธ ๋งคํ ์๋ํ |
| Spring Security | ์ธ์ฆ/์ธ๊ฐ ํ๋ ์์ํฌ | ๋ณด์ ์ค์ ๋ฐ API ๋ณดํธ |
| Lombok | ๋ฐ๋ณต ์ฝ๋ ์๋ต์ ์ํ ์ ๋ํ ์ด์ ์ฒ๋ฆฌ๊ธฐ | Getter/Builder ์๋ ์์ฑ |
| MySQL Connector/J | MySQL์ฉ JDBC ๋๋ผ์ด๋ฒ | DB ์ฐ๊ฒฐ |
| AWS SDK for Java (S3) | AWS ์๋น์ค ์ฐ๋ | ์ด๋ฏธ์ง ํ์ผ S3 ์ ๋ก๋ ๋ฐ ๋ฒํท ๊ด๋ฆฌ |
| PortOne REST Client | ํฌํธ์ ๊ฒฐ์ ์ฐ๋ ๋ชจ๋ | ๊ฒฐ์ API ํธ์ถ ๋ฐ ์ํ ๊ฒ์ฆ |
| Hibernate | JPA ๊ตฌํ์ฒด | Entity ๊ธฐ๋ฐ DB ์กฐ์ ๊ธฐ๋ฅ ๊ตฌํ |

