ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ์ฝ๋ ์ ๋ฆฌ์ ์ด๋ ค์์ ๊ฒฉ์ด ์ํคํ ์ฒ ๊ด๋ จ ํ์ต ํ ๋ฐฐ์ด ์ ์ ์ ์ฉํ์ฌ ๋ฆฌํฉํฐ๋ง ์ค์ ๋๋ค.
https://github.com/ch-yang1273/StudyCafe_SpringBoot/tree/v1.0
- ๊ฐ ๋ ์ด์ด์ ์ญํ ์ ๊ตฌ๋ถ (Controller, Service, Repository, Domain)
- ํจํค์ง ๊ฐ ์ํ์ด ๋ฐ์ํ์ง ์๋๋ก ์์กด์ฑ์ ์ ๋ฆฌ
- ํ ์คํธํ๊ธฐ ์ข์ ์ฝ๋๋ฅผ ์์ฑํ๊ณ , ๋จ์ ํ ์คํธ ์์ฑ
- GitHub Actions๋ฅผ ์ฌ์ฉํ์ฌ CI/CD ์ ์ฉ
- 2023๋ 3์ 11์ผ ~ 2023๋ 5์ 31์ผ
- ๋๋ฉ์ธ ์ฃผ๋ ๊ฐ๋ฐ ์์ํ๊ธฐ (์ต๋ฒ๊ท )
- 190620 ์ฐ์ํ๊ฐ์ฒด์งํฅ (์กฐ์ํธ)
- ๋จ์ ํ ์คํธ (๋ธ๋ผ๋๋ฏธ๋ฅด ์ฝ๋ฆฌ์ฝํ)
โ ํจํค์ง ๊ตฌ์กฐ ์ ๋ฆฌ
- layer ๋จ์๋ก ๊ตฌ๋ถํ๋ ํจํค์ง ๊ตฌ์กฐ๋ฅผ ๋๋ฉ์ธ ๋จ์๋ก ๋ณ๊ฒฝ
- Entity์ ์ฐ๊ด ๊ด๊ณ์ ๋ง์ถฐ ํจํค์ง ๊ฐ ์์กด์ฑ ์ ํ
โ ํจํค์ง ์์กด์ฑ ์ํ ํด๊ฒฐ
-
Follow ๋๋ฉ์ธ ์ถ๊ฐ
User๊ฐ ์ฌ์ฉ ์ค์ธ Cafe ์ ๋ณด๋ฅผ User Entity๊ฐ ๊ฐ๊ณ ์๊ณ , Cafe ๋๋ถ๋ถ ์๋น์ค๋ User๋ฅผ ์์กด
-> User๊ฐ ์ฌ์ฉ ์ค์ธ Cafe ์ ๋ณด๋ฅผ Follow Entity์ ์ด๊ดํ์ฌ Cafe์ ๋ํ ์์กด์ฑ์ ์ ๊ฑฐ
-
์ข์ ์์ฝ ๊ธฐ๋ฅ์ Seat์์ Reservation์ผ๋ก ์ด๋
Reservation์ด ์์ฝํ Seat ์ ๋ณด๋ฅผ ํฌํจํ๊ณ , Seat์ ์๋น์ค๊ฐ Reservation์ ์์ฑํ๋ฉด์ ์์กด์ฑ์ด ์ํ
-> Reservation ์๋น์ค์์ ์์ฝ์ ์งํํ๊ณ , Seat์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ๋ฉด์ ๋จ๋ฐฉํฅ ์์กด์ฑ์ผ๋ก ๋ณ๊ฒฝ
โ CQRS ํจํด ์ ์ฉ
- ๋ช ๋ น์ void๋ฅผ ๋ฐํํ๊ณ , ์กฐํ๋ DTO๋ฅผ ๋ฐํ
- Read์ CUD๋ฅผ ๋ถ๋ฆฌํ์ง๋ ์์์
โ ํ ์คํธํ๊ธฐ ์ข์ ์ฝ๋ ์์ฑ
- ์ธ๋ถ ์์กด์ฑ์ด ์๋ ์ฝ๋์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ถ๋ฆฌํ๊ณ , ๋จ์ ํ ์คํธ ์์ฑ
- ์คํ ์ฝ๋ ์์
- ํ ์คํธ ์ฝ๋ ์์
โ ์๊ฐ ๋ฉ์๋ ํ ์คํธ (์์ฑ์, ์ ์ ๋ฉ์๋)
// ๊ธฐ์กด ์ฝ๋ (v1.0 JwtTokenProvider.java)
public String createAccessToken(String subject) {
Date now = new Date();
Date expireDate = new Date(now.getTime() + expireTime);
...
}
- ์ฝ๋์
new Date()
์ ๊ฐ์ ์๊ฐ ๋ฉ์๋๋ ํ ์คํธ์์ ์ ์ด๊ฐ ์ด๋ ค์ - ์์ฑ์์ Static ๋ฉ์๋๋ Mocking์๋ ์ถ๊ฐ์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(mockito-inline, PowerMokito)๊ฐ ํ์
// ์์ ์ฝ๋ (v2.0 JwtTokenService.java)
public String createAccessToken(TokenPayload payload, Date now) {
Date expireDate = new Date(now.getTime() + expireTime);
...
}
- ์๊ฐ ๋ฉ์๋ ์์กด์ฑ์ ์์ ๋ ์ด์ด๋ก ๋นผ๋ด์ด, Mocking ์์ด ๋จ์ ํ ์คํธ ๊ฐ๋ฅ
- ์๊ฐ ๋ฉ์๋๋ CurrentTimeProvider ์ธํฐํ์ด์ค๋ก ์ถ์ํํ์ฌ ์ฌ์ฉ
- ํตํฉ ํ ์คํธ์์๋ mockito-inline ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด CurrentTimeProvider๋ฅผ Mocking
Github Actions๋ฅผ ์ด์ฉํ์ฌ CI/CD๋ฅผ ์ ์ฉํ์ต๋๋ค.
- Master Branch ์ธ์ Branch์ Push ์, Github Actions๋ฅผ ํตํด ํ ์คํธ๋ฅผ ์งํ
- Master Branch์ Push ์, ํ ์คํธ๋ฅผ ์งํํ๊ณ , AWS CodeDeploy๋ฅผ ํตํด ๋ฐฐํฌ
๐จ CI (All branch)
flowchart LR
A[Push] --> B[Container Init] --> C[๋น๋ ํ๊ฒฝ ๊ตฌ์ฑ] --> D[๋น๋ ํ๊ฒฝ Caching] --> E[๋จ์/ํตํฉ ํ
์คํธ]
- MariaDB, Redis Container๋ฅผ Init ํ์ฌ ๋จ์/ํตํฉ ํ ์คํธ ์งํ
- ๋น๋ ํ๊ฒฝ Caching๋ฅผ ํตํด ๋น๋ ์๋๋ฅผ ๋์
- ci.yml
๐จ CI/CD (master branch)
flowchart LR
A[Push] --> B([CI: Test & Build]) --> C[๋น๋ ํ์ผ ์์ถ] --> D[AWS ์ธ์ฆ ์ ๋ณด ์ค์ ] --> E[S3 ์
๋ก๋] --> F[S3์์ EC2๋ก ๋ฐฐํฌ]
- Master Branch์์๋ CI์ ์ถ๊ฐ๋ก ๋ฐฐํฌ(CD)๊น์ง ์งํ
- ๋น๋ ํ์ผ์ S3์ ์ ๋ก๋ํ๊ณ , CodeDeploy๋ฅผ ํตํด ๋ฐฐํฌ
- ๋ฐฐํฌ ํ application.properties๋ฅผ Production ์ฉ์ผ๋ก ๊ต์ฒดํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ฌ์์
- cicd.yml
- application-start.sh
- ๋จ์ ํ ์คํธ ์ถ๊ฐ
- Ticket ๋๋ฉ์ธ ์ฝ๋ ์ ๋ฆฌ
- Orders, Product ๋๋ฉ์ธ ์ฝ๋ ์ ๋ฆฌ
- ๊ฐ ๋๋ฉ์ธ์์ VO ์ธ๋ถํ
- Repository Entity์ User์ Cafe์ ๋ํ ์์กด์ฑ ์ ๊ฑฐ (์ฐ๊ด ๊ด๊ณ๊ฐ ๋ง์)
- Admin ๊ธฐ๋ฅ๊ณผ User ์๋น์ค ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข๊ฒ ์
- 2022๋ 11์ 01์ผ ~ 2023๋ 2์ 9์ผ
- ch-yang1273
- padonan
- springBoot โ2.7.5โ
- jdk 11
- gradle '7.5.1'
- h2 โ2.1.214โ
- QueryDsl '5.0.0'
- jwt '0.11.5'
- swagger '1.6.13'
- bootpay.backend.java // ๊ฒฐ์ ๋ชจ๋
- junit '5'
Git : (https://github.com/padonan/asc_flutter)
- flutter โ3.3.4โ
- dart โ2.18.2โ
- flutter_native_splash: ^2.2.13
- intl: ^0.17.0
- qr_flutter: ^4.0.0
- dio: ^4.0.6
- flutter_secure_storage: ^6.0.0
- jwt_decoder: ^2.0.1
- bootpay: ^4.4.3
- flutter_form_builder: ^7.7.0
- toast: ^0.3.0
- url_launcher: ^6.1.7
- logger: ^1.1.0
- flutter_local_notifications: ^12.0.4
- build_runner: ^2.3.2
- json_serializable: ^6.5.4
โจ ํต์ฌ ์๋น์ค๋ ์คํฐ๋์นดํ ์ด์ฉ, ๊ฒฐ์ ๊ถ ๊ตฌ์ , ADMIN์ ์คํฐ๋์นดํ ๊ด๋ฆฌ์ ๋๋ค.