일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 백준#BOJ#1939#중량제한
- 백준#BOJ#2615#오목
- 백준#boj#12755
- 백준#BOJ#12865#평범한배낭
- 백준#BOJ#14501#퇴사#브루트포스
- 백준#boj#16932#모양만들기
- 백준#BOJ#8012#한동이는영업사원
- Today
- Total
순간을 성실히, 화려함보단 꾸준함을
긴 여정을 마치고....(토이 프로젝트 마무리) 본문
안녕하세요.
정말 오랜만에 글을 작성합니다.
글또 9기에 참여를 하였지만,,,,,,글을 꾸준하게 작성하지 못해 이번 기수에는 실패한 것 같네요 ㅠㅠㅠㅠ
그럼에도 불구하고 글또와 별개로 토이 프로젝트를 마무리한 경험을 토대로 글을 작성해 보려고 합니다.
2024년 2월 날짜로 토이 프로젝트를 마무리 하였습니다. 이 프로젝트를 통해서 성과(?)는 아니지만 학습하고 적용했던 것들을 나열해보도록 하겠습니다.
1. java + spring boot + jpa + querydsl 조합으로 개발 진행
저는 현재 정통 대기업에서 sm (운영직무) 를 수행하고 있습니다. java 와 oracle database 를 다루고 있어 아무래도 java 를 기반으로 개발할 수 있는 spring boot 프래임워크를 선택하였습니다.(회사에서는 spring 도 사용 못하고 있습니다...ㅠ)
또한, 김영한님의 jpa 시리즈를 학습하고 이를 직접 체득하는 과정이 필요할 듯 싶어 jpa + querydsl 을 이용하여 개발하였습니다. 확실히 강의를 들을때와 달리 직접 개발을 하면서 부딧쳐야지 정말 제 것이 되는 것 같습니다.
프로젝트가 마무리가 될 때까지 큰 이슈 없이 해당 스택들로 개발을 끝낼 수 있었습니다.
2. email 전송 시에 비동기처리(@Async + @EnalbeAsync)
해당 프로젝트 기능 중에는 email 을 전송하는 기능이 있습니다. spring boot 의 JavaMailSender 클래스를 이용하여 메일을 보낼 수 있습니다. 이를 이용하여 이메일을 전송하는 api 를 개발하였는데.....이상하게 굉장히 늦게 응답을 하더라구요.
아마 외부 네트워크를 통해 전송을 하는 거다 보니 이메일 전송이 완료되고 응답되기까지 시간이 꽤 소묘되는 것 같았습니다.
만약 사용자가 이메일을 전송하고 완료되었다는 응답을 이렇게나 오랜 시간동안 대기 해야한다면 굉장히 불편함을 느끼겠죠?? 그리고 사용자입장에서는 실제로 이메일이 전송되는 시간보단 본인에게 이메일이 전송이 완료되었다는 응답을 받는 것이 더 포커스가 맞추어져 있습니다. 즉, 이메일이 실제로 전송되기만 하면 되는 것이지 살짝 늦게 전송되었다는 것에 대해 큰 불편함을 느끼지는 못하는 거죠.
그래서 이를 비동기 처리로 구현했습니다. 실제 이메일을 전송하는 task 와 사용자에게 이메일을 정상적으로 전송완료했다고 응답하는 task 를 분리하여 생각했습니다.
이렇게 개선을 하고 난 뒤 이메일 전송을 하였을때 바로 사용자에게 완료되었다는 응답을 보내주어 훨씬 서비스를 이용하는데 있어 불편함을 개선시킬 수 있었습니다.
@Async 어노테이션을 사용했습니다. 그러나 조금 더 찾아보니 @Async 어노테이션을 사용하는 것 보다는 AsyncConfigureSupport 를 상속받아 getAsyncExcutor() 를 재정의하는 것이 더 좋다고 합니다.
[출처 : https://dkswnkk.tistory.com/706]
저도 이번 기회에 실제로 비동기처리를 어떻게 구현하는지? SimpleAsyncTaskExecutor 와 ThreadPoolTaskExecutor 의 차이점이 무엇인지? 에 대한 내용을 학습할 수 있었습니다.
3. http 요청시 preflight 요청은 어떻게 처리해야 할까??
sop (same origin policy) 와 cors (cross origin resource sharing) 에 대해서는 다들 알고 계시죠???
해당 내용은 너무 중요하고 기본이라서 반드시 꼭 알고 가시길 바라겠습니다.
[참고 영상 : https://www.youtube.com/watch?v=6QV_JpabO7g]
cors 동작을 구현하는 방식 중에 가장 널리 사용되는 방법이 preflight request 인데요 실제 api 요청 전에 내가 전송할 요청이 정상적인지 아닌지를 확인받을 수 있는 선요청을 먼저 날리게 됩니다. 만약 유효한 요청이 아니라면 웹브라우저는 요청자체를 차단시키게 됩니다.
전 jwt 에 대한 검증을 spring interceptor 를 통해서 검증을 시도했습니다. 해당 토큰이 유효한지 아닌지를 체킹하는 로직인데 preflight 요청이 발생할때도 interceptor 로 요청이 들어가게 됩니다. 그러나 interceptor 에서는 해당 요청을 처리할 수 있는 기능이 없다보니 cors 에러가 발생하게 되더라구요.
interceptor 에서 preflight 요청이 발생했을때 처리할 수 있는 기능을 추가하였습니다.
CorsUtils.isPreFlightRequest 라는 객체를 사용해서 이 문제를 해결 할 수 있었습니다.
4. @EventListner 를 사용하여 의존성을 분리해 보자
일기방이 있고 일기방에는 사용자를 초대할 수 있습니다. 이때 초대받은 사용자에게 이메일을 전송하도록 기능이 짜여져 있는데요. 이 모든 기능을 하나의 task 에 담기에는 너무 많다고 생각이 되었습니다.
객체끼리도 의존성이 늘어나게 되고, 결합이 강해지게 된다는 단점이 존재합니다.
그래서 이를 뜯어내고 느슨한 결합 구조로 만들기 위해서 @EvnetListner 를 이용하였습니다.
일기방에 사용자를 초대하고 난뒤에 eventListner 에서 입력한 이메일들 주소로 메일을 전송하도록 구현했습니다.
이벤트를 처리할 인터페이스를 선언하고,
이벤트가 발생하면 처리할 구현체를 정의해 주었습니다.
ApplicationEventPublisher 에 publishEvent 메소드를 이용하여 정의한 객체를 파라미터로 넘겨주면 자동으로 이벤트가 실행되게 되는거죠.
이렇게 어쩌면 복잡할 수도 있는 로직을 @EvnetListner 를 통해서 결합성을 분리하여 해당기능을 구현할 수 있었습니다.
5. Test Code 는 왜 작성해야 되고, 어떻게 작성할 수 있을까???
이번 프로젝트에 다양한 test code 를 작성하려고 노력했습니다.
RestAssured 를 사용한 e2e test
service layer 통합 테스트 작성
domain 별 query 작성 메소드 test
위 과정에서 mocking,stubbing 도 해보면서 더 좋은 test code 는 무엇이고 어떻게 test code 를 작성할 수 있을까? 라는 생각들을 할 수 있었습니다.
위 강의를 통해서 학습했던 내용들을 직접 적용시켜 보았는데요, 너무나도 알차고 좋은 강의였습니다.
다른분들도 기회가 되시면 꼭 수강하시길 바라겠습니다.
또한, 매 테스트가 종료된 후 DB 에 남아있는 잔재들을 어떻게 초기화 시킬 수 있을지에 대해서 고민을 해보았습니다. 가장 첫번째로는 @Transactional 어노테이션을 사용하는 것이었는데 해당 어노테이션은 주의할 점이 있습니다.
위 글을 참고해보세요!!!
그래서 @Transactional 을 사용하는 방법은 배제했습니다. 그러던 중 우아한tech 세미나 영상에서 아래와 같은 영상을 발견했습니다.
https://www.youtube.com/watch?v=ITVpmjM4mUE&list=PLgXGHBqgT2TtGi82mCZWuhMu-nQy301ew&index=26
영상이 조금 긴데 소스는 아래 링크를 타고 들어가시면 됩니다.
이번 글을 여기서 마치고 다음 글에서는 docker 를 사용해서 개발환경을 세팅한 경험, github Action 을 사용해서 CI/CD 를 구축한 경험, AWS ec2, route53, acm, load balancer 를 통해 운영서버에 배포와 https 를 적용한 경험 등등을 작성해보도록 하겠습니다.
글을 읽어주셔서 감사드립니다!
'나의 개발 메모장' 카테고리의 다른 글
[토이 프로젝트] 마무리 (0) | 2024.05.04 |
---|---|
[OSS] 나만의 Redis Command 만들어보기 (0) | 2024.04.27 |
대용량 데이터는 어떻게 관리해야 되는 걸까? (0) | 2024.01.20 |
2023년 회고 (3) | 2023.12.30 |
[Docker] docker-compose 첫 사용기! (0) | 2023.12.24 |