Project

    ๋ธ”๋กœ๊ทธ

    ์š”์ฆ˜ ์ทจ๋ฏธ๊ฐ€ ๋งŽ์ด ์ƒ๊ธด๊ฒƒ ๊ฐ™๋‹ค.(๋“ฑ์‚ฐ, ์บ ํ•‘, ํŽŒํ”„ ๋“ฑ..) ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ๋‚˜ ์˜์ƒ์„ ์ฐ์–ด ์˜ฌ๋ฆด๊นŒ ์ƒ๊ฐ์ค‘์ธ๋ฐ ๋˜ ์‹œ์ž‘ํ•˜๋ ค๋ฉด ๊ฐ์žก๊ณ ... ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๊ฐํ•  ์‹œ๊ฐ„์ด ํ•„์š”ํ•˜๋‹ค. ์ƒ๊ฐํ•  ์‹œ๊ฐ„๋™์•ˆ ์ฝ”ํ‹€๋ฆฐ ๊ณต๋ถ€๋ฅผ ์‹œ์ž‘ํ•ด๋ณด๋ ค๊ณ  ์ฝ”ํ‹€๋ฆฐ + spring ์œผ๋กœ ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ค ์ƒ๊ฐ์ด๋‹ค. ์ „๋ถ€ ์•ˆ์“ฐ๊ณ  ๋ชป์“ฐ๋˜ ๊ธฐ์ˆ ์„ ์ฐพ์•„์„œ ์‚ฝ์งˆํ•  ์˜ˆ์ •. ์šฐ์„  ํŒ€์žฅ๋‹˜์ด ์ถ”์ฒœํ•ด์ฃผ์‹  1. CI/CD ์ ์šฉ + ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ 2. ECS ์„œ๋ฒ„ (๋ฅผ ์œ„ํ•ด +Docker) 3. Spring Webflux ํ”„๋ ˆ์ž„์›Œํฌ (Coroutine) 4. ์บ์‹œ์„œ๋ฒ„ (redis) ๋ธ”๋กœ๊ทธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ์—” ๊ณผํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ณต๋ถ€์šฉ์œผ๋กœ...๋ชจ๋‘ ์ ์šฉํ•  ์˜ˆ์ •์ด๋‹ค ๊ธด ์‹ธ์›€์ด ์˜ˆ์ƒ๋œ๋‹ค ^^...

    8. Service

    @RequiredArgsConstructor @Service public class DiaryRegisterService { private final CoupleRepository coupleRepository; private final DiaryRepository diaryRepository; private final UserRepository userRepository; public DiaryRegisterResponse addDiary(DiaryRegisterRequest diaryRegisterRequest) { Couple couple = coupleRepository .findByCoupleToken(diaryRegisterRequest.getCoupleToken()) .orElseThrow(..

    7. CI/CD ๊ณ„ํš

    ๋ฆฌํŒฉํ† ๋ง์ด 30%์ •๋„ ๋‚จ์€ ์‹œ์ ์—์„œ ์ž๋™ํ™” ๋ฐฐํฌ๋ฅผ ๊ณ„ํšํ•˜๊ณ ์žํ•ฉ๋‹ˆ๋‹ค! ์šฐ์„  ์ฒ˜์Œํ•ด๋ด์„œ ๊ฒ€์ƒ‰์œผ๋กœ ์ฐพ์•„๋‚ธ ๋ฐฉ๋ฒ•์„ ์‹คํ–‰ํ•œ ํ›„ ๋ฐฉ์‹์„ ์ดํ•ดํ•˜๊ณ  ๋‹ค๋ฅธ๊ฑธ๋กœ ๋ฐ”๊ฟ”๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์ œ์ผ ๋งŽ์ด ๋“ค์–ด๋ดค๋˜ Jenkins, Docker๋ฅผ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. 1. GitHub Push. 2. GitHub์—์„œ Jenkins์— Build ์œ ๋ฐœํ•œ๋‹ค. 3. Jenkins์—์„œ Gradle Buildํ•˜์—ฌ Jar ํŒŒ์ผ ์ƒ์„ฑ ํ•œ๋‹ค. 4. ์ƒ์„ ๋œ Jar ํŒŒ์ผ์„ build ํ•œ๋‹ค. 5. DocerHub์— Push ํ•œ๋‹ค. 6. Jenkins ๊ฐ€ DockerHub์— ์žˆ๋Š” ํŒŒ์ผ์„ pull ํ•œ๋‹ค. 7. ์ด์ „ ์ปจํ…Œ์ด๋„ˆ ์‚ญ์ œ ํ›„ ์ƒˆ๋กœ ๋ฐ›์•„์˜จ ์ด๋ฏธ์ง€๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. https://velog.io/@haeny01/AWS-Jenkins%EB%A5%BC-%ED%99%9..

    6. ๋ฌด์—‡์ด ๋ฌธ์ œ์ผ๊นŒ ...

    Test ๋„์ค‘ ์ด์ƒํ•˜๊ฒŒ ResponseFileds๋ฅผ ๋ฐ›์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค. ํ˜น์‹œ๋‚˜ ํ•ด์„œ postman์œผ๋กœ ํ…Œ์ŠคํŠธ ํ•ด๋ณด์•˜๋Š”๋ฐ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž˜๋‚˜์˜จ๋‹ค ... ํ…Œ์ŠคํŠธ๋Š” ์„ฑ๊ณตํ•˜์ง€๋งŒ responseFields ๊ฐ€ ์—†๋‹ค๋ฉฐ ๊ณ„์†ํ•ด์„œ ์˜ค๋ฅ˜๋ฅผ ๋ฑ‰๋Š”๋‹ค ... ใ…œใ…œ ๋ฌด์—‡์ด ๋ฌธ์ œ์ผ๊นŒ @Test void loginUser() throws Exception { final UserLoginRequest userLoginRequest = UserLoginRequest.builder().socialToken("Asd823daz").pushToken("Wesdf0898dfa").build(); final UserLoginResponse userLoginResponse = UserLoginResponse.builder().coupleT..

    5. Spring REST Docs ์‚ฌ์šฉ

    ์„œ๋น„์Šค ๊ตฌํ˜„์— ์•ž์„œ REST API ๋ฌธ์„œ๋ฅผ ์ž๋™ํ™” ํ•ด์ฃผ๋Š” Spring REST Docs ๋ฅผ ์‚ฌ์šฉํ•ด๋ณธ๋‹ค. Docs๋ฅผ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” Test์—์„œ ์„ฑ๊ณตํ•ด์•ผ๋งŒ ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ•˜๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ•์ œ๋กœ TEST CODE๋ฅผ ์ž‘์„ฑํ•˜์—ฌ API์— ๋Œ€ํ•œ ์‹ ๋ขฐ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. Gradle 7์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ ๋ฌธ์„œ์ƒ์„ฑ์ด ์•ˆ๋˜์„œ ๊ฒ€์ƒ‰ํ•ด๋ดค๋‹ค. ์šฐํšŒ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ ๋ณต์žกํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์„ ํƒํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Gradle๊ณผ Maven ์—์„œ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งจ์•„๋ž˜ ๋งํฌ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ด๋ณด๋Š” ๊ฒƒ๋„ ์ข‹๋‹ค! ํ™˜๊ฒฝ์„ค์ • Springboot 2.6.1 Gradle 6.9.1 JUnit5 Asciidoctor 1.5.9.2 build.gradle ์— ์ถ”๊ฐ€ํ•œ ์„ค์ • plugins { id "org.a..

    4. ์—ฐ๊ด€๊ด€๊ณ„ - OneToMany

    DiaryEntity package so.ego.re_darling.domains.diary; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import so.ego.re_darling.domains.user.domain.Couple; import javax.persistence.*; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; @Gette..

    3. ์—ฐ๊ด€๊ด€๊ณ„ - ManyToOne

    Coupon Entity package so.ego.re_darling.domains.coupon.domain; import lombok.*; import so.ego.re_darling.domains.user.domain.User; import javax.persistence.*; import java.time.LocalDateTime; @AllArgsConstructor(access = AccessLevel.PROTECTED) @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "coupon") @Entity public class Coupon { @Id @GeneratedValue(strategy = GenerationType.IDEN..

    2. Entity

    package so.ego.re_darling.domains.coupon.domain; import lombok.*; import javax.persistence.*; import java.time.LocalDateTime; @AllArgsConstructor(access = AccessLevel.PROTECTED) @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "coupon") @Entity public class Coupon { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @NonNull private String title; private Str..

    NAWA ํ”„๋กœ์ ํŠธ ์„ค๋ช…

    1. ๋ฌธ์„œ ์ž‘์—… ๋ฌธ์„œ ์ž‘์—…์€ ์˜ˆ์ƒ๋งŒํผ์ด๋‚˜ ์–ด๋ ต๊ณ  ์‹œ๊ฐ„์ด ๋งŽ์ด ๋“ค์–ด๊ฐ”๋‹ค. ์ฒ˜์Œ์œผ๋กœ ๊ฐœ๋ฐœ ์˜ˆ์ • ๋ณด๊ณ ์„œ๋กœ ์—ญํ• ๋ถ„๋‹ด, ์ผ์ •, ์‹œ์Šคํ…œ ๊ตฌ์„ฑ๋„, ๊ตฌํ˜„์„ ์ž‘์„ฑํ•˜์˜€๋‹ค. ํ•™์›์—์„œ ๊ฐ™์ด ๋ฐฐ์šด ์–ธ์–ด์™€ ๊ฐœ๋ฐœ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋ ต์ง€ ์•Š์•˜๋‹ค. ์—ญํ• ๋ถ„๋‹ด์—์„œ ๊ฐœ์ธ์˜ ์—ญ๋Ÿ‰ ์ฐจ์ด ๋•Œ๋ฌธ์— ์กฐ๊ธˆ ์‹œ๊ฐ„์ด ์ง€์ฒด๋˜์—ˆ์ง€๋งŒ, ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ ์ถ”๊ฐ€, ์ˆ˜์ •๋˜์—ˆ๋‹ค. ๊ทธ ํ›„ ๊ธฐ๋Šฅ์ •์˜์„œ (FBS)๋ฅผ ์‹œ์ž‘ํ•˜๋ฉฐ ์ •๋ง ํž˜๋“ค์—ˆ๋‹ค... ๊ทธ ํ›„์— ๋งŒ๋“  ๋ฌธ์„œ์—์„œ ์กฐ๊ธˆ์ด๋ผ๋„ ๋ฐ”๋€Œ๋ฉด FBS๋„ ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด์–ด์„œ ์ฒ˜์Œ ๊ณ„ํšํ•  ๋•Œ ์ข€ ๋” ์‹ ์ค‘ํ–ˆ์–ด์•ผ ํ–ˆ๋‹ค๋Š” ๊ฑธ ๋ผˆ์ €๋ฆฌ๊ฒŒ ๋А๊ผˆ๋‹ค... ๊ตฌํ˜„๋˜์–ด์•ผ ํ•  ๊ธฐ๋Šฅ์ด ํ•˜๋‚˜ํ•˜๋‚˜ ๋‚˜์—ด๋˜์–ด์žˆ๋‹ค. ๋Œ€๋ง์— ์š”๊ตฌ์‚ฌํ•ญ ๋ช…์„ธ์„œ , ๊ฐ€์žฅ ์‹œ๊ฐ„์„ ๋งŽ์ด ์Ÿ์•„๋ถ€์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ๋ฐœํ•  ๋•Œ ๋ฌด์ฒ™ ๋„์›€์ด ๋งŽ์ด ๋˜์—ˆ๋‹ค. ํŒ€ ํ”„๋กœ์ ํŠธ์ด๋‹ค ๋ณด๋‹ˆ ์„œ๋กœ ..