본문 바로가기

분류 전체보기

(90)
7기 프리코스 1주차 회고(알고 있다고 생각했던 것들) 1주차 프리코스를 진행하며 아는 것과 모르는 것을 구분하는 법을 배울 수 있었다.평소 알고 있다고 생각하고 사용했던 개념들에 대해 꼬리질문을 하니 대답할 수 없던 경우가 많았다. 과제를 진행함에 있어 내가 알고 있다고 생각했지만, 몰랐던 것들에 대해 정리를 해 보고자 한다.    1. 자바의 record 클래스알고 있던 개념1. record 는 단순히 값을 저장하는 용도의 클래스가 필요할 때 사용하는 클래스 타입이라는 점.2. 내부 변수를 얻기 위해선(get), 변수명과 동일한 메서드로 접근하면 된다는 것(ex. record.value()).  더 조사하게 된 계기1. 불변 객체를 만들기 위해 record 클래스를 만들고, 변수에 private final 을 붙였다. 하지만, 문법 오류가 발생했다. 2...
Redis 캐싱만 적용하면 끝일까? - Resilience4j 를 통한 Circuit Breaker 적용 Redis를 사용해 응답 데이터를 캐싱했다고 가정해 보자. Redis의 TTL  동안 오는 모든 요청은 Redis와 통신해야 한다.  Look - Aside 패턴을 사용해 캐싱했다고 가정해 보자. 요청을 받은 애플리케이션은 우선 Redis에 해당 데이터가 존재하는지 확인해야 한다. 존재한다면 Redis의 데이터를 반환할 것이고, 존재하지 않는다면 DB에서 직접 값을 읽은 후, Redis에 삽입한 후, 반환할 것이다.  그렇다면.. 만약 Redis에서 장애가 발생해 Redis와 연결이 끊기면 어떻게 될까? Redis에 연결할 수 없으므로, 별다른 처리가 없다면 500 Internal Server Error 가 발생할 것이다.이는 모놀리식 아키텍처에서도 문제이지만, MSA에서는 더 큰 문제이다. 더보기왜 M..
Spring Boot에서 Redis를 활용해 데이터 캐싱하기(feat. Look Aside) 캐시는 자주 사용되는 데이터를 미리 복사해 저장하는 임시 저장소이다. 다음과 같은 상황에서 캐시를 사용할 수 있다. 같은 데이터에 반복적으로 접근하는 상황동시에, 해당 데이터의 변경이 적은 상황캐시를 구현하기 위해 Redis가 많이 사용된다. 그 이유는 다음과 같다.Redis는 In memory 데이터베이스로, Key, Value 쌍을 저장하는 일종의 NoSQL DB이다. In memory 데이터베이스이므로, 하드 디스트에 데이터를 저장하는 일반적인 데이터베이스보다 속도가 월등히 빠르다. 물론, 단점도 있다. 접근 속도에 대한 Trade Off로 비싸다. 비싸다는 것은, 용량이 적다는 것을 나타낸다. 따라서, 많은 데이터를 Redis에 저장하기엔 한계가 있다. 캐싱을 잘 사용하면 특정 상황에서 애플리케이..
캐싱, 개념과 읽기 전략들 다음과 같은 상황을 가정해보자. 상품 판매 서비스를 개발하고 있다.상품 조회 API를 개발하고 있는데, 상품의 정보는 거의 바뀌지 않지만, 매 요청마다 DBMS에 쿼리를 날려 다시 조회하고 있다. 이 상황의 문제점은 다음과 같다. 변경 빈도가 매우 낮은 데이터를 얻기 위해 매번 DB에 쿼리를 보내 애플리케이션의 성능이 떨어지고 있다! 이것이 왜 문제일까? 1. DBMS는 기본적으로 Disk에 데이터를 저장한다. Disk는 용량은 크지만, 접근 시간이 느리다는 단점이 있다.2. 상품 데이터가 100만개라고 가정하면, 매 조회마다 Disk에 접근해야 한다.3. 매번 DBMS에 쿼리를 날리지만, 응답 데이터는 거의 항상 똑같다.  이 비효율성을 해결하기 위해 똑똑한 사람들이 한 가지 방법을 생각해냈다. 변경이..
조금 많이 늦은 11기 마무리와 12기 운영진 시작 11기에서 활동하며 "개발"이라는 것을 처음 접했다. 쉬운 알고리즘 문제나, 심심풀이로 구현을 해 보는 게 전부였던 나에게 11기 활동은 정말 큰 행운이었다. 웹 개발을 처음 접하고, 백엔드 개발도 처음 접했다. 아무것도 모르는 상태에서 시작했기에 세션을 따라가기 힘들었지만, 개발이 즐거웠기에 버틸 수 있었다. 해커톤을 하며 나보다 뛰어난 팀원과의 소통도 경험해 볼 수 있었고, 스스로에 대한 부족함도 많이 느꼈다.해커톤 당시에는 자괴감이 많이 들었다. 지금도 마찬가지지만, 세상은 매우 넓고 나보다 뛰어난 사람은 널렸다...이 자괴감은 곧 지식에 대한 갈증으로 변화되었다. 해커톤이 끝나고, 진정한 방학이 시작되었지만, 해커톤 코드를 리팩터링하고 부가적인 기능을 계속해서 추가하며 스스로 공부하기 시작했다...
Interceptor를 활용한 JWT 토큰 검증 인증, 인가를 위해 매 요청마다 JWT를 검사해야 한다.하지만, 이 과정을 비즈니스 로직 내부로 가져오기엔 무리가 있다. 인증, 인가는 비즈니스 로직의 책임이 아니다. 비즈니스 로직을 구현하는 객체는 자신의 책임에만 집중해야 한다.유지보수성이 좋지 않다. Util Class로 분리해도, 결국 Service들은 해당 Util Class에 의존해야 하기 때문이다. 즉, Class 간 결합도가 높아진다. 인증, 인가를 비즈니스 로직에서 빼내보자.Controller에 요청이 도착하기 전에 인증, 인가가 수행할 것이다.Controller 앞에서 구현하면 다음과 같은 이점을 가질 수 있다. 모든 요청이 Controller에 도달하기 전에 인증과 인가가 처리되므로, 인증되지 않은 접근이나 권한이 없는 요청을 사전에 ..
Dto Validation 실패 시 예외처리 우리는 Dto를 사용하면서 여러 Validation 어노테이션을 사용한다. 학생을 저장하는 요청의 Dto를 살펴보자 @Getter public class ApplicationSaveDto { @NotNull(message = "학번이 누락되었습니다.") @Pattern(regexp = APPLICATION_STUDENT_ID_PATTERN, message = "학번이 형식에 맞지 않습니다.") private String studentId;//학번 @NotNull(message = "이름이 누락되었습니다.") @Pattern(regexp = APPLICATION_NAME_PATTERN, message = "이름이 형식에 맞지 않습니다.") private String name;//이름 @NotNull(mes..
Spring Boot에선 예외를 어떻게 처리할까?(전역, 커스텀 예외처리) 프로그램을 개발하다 보면, 예외를 던지는 상황이 생긴다. try, catch, finally를 사용해 이 예외를 다룰 수 있다. 하지만, 이는 프로젝트 규모가 커지면 코드 중복, 리소스 낭비 등으로 이어진다. Spring Boot에서는 이 예외를 어떻게 다룰까? 우선, Spring Boot는 실행 중 발생한 예외는 기본적으로 처리해 준다.   하지만, 이런 Response는 프론트엔드 입장에서 알아보기 어렵다. 회원가입 시 이름, 이메일, 전화번호를 POST로 우리 서버에 보내는 상황에서 HTTP 400 만으로는 이름이 잘못되었는지, 전화번호가 잘못되었는지 알 수 없다. (Message를 사용하긴 하지만, 프론트의 코드로 Message를 구별하긴 힘들다. 특히 규모가 커질수록…) 이런 문제가 생기지 않..
Spring Boot의 ResponseEntity Spring Boot에선 기본적으로 ResponseEntity 라는 클래스를 제공한다. 이는 Http 요청에 대한 Response를 설정할 수 있는 클래스로, Body, Header, StatusCode를 설정할 수 있다.  이 ResponseEntity 클래스를 사용해 적절한 Response를 보낼 수 있다.  ResponseEntity는 HttpEntity를 상속받는다.public class HttpEntity { private final HttpHeaders headers; @Nullable private final T body;}public class ResponseEntity extends HttpEntity { private final HttpStatusCode status; pub..
Dto에 Validation 적용하기 build.gradle에 다음을 추가한다. implementation 'org.springframework.boot:spring-boot-starter-validation' validation 어노테이션 목록은 다음과 같다. @Null - // null만 혀용합니다. @NotNull - // null을 허용하지 않습니다. "", " "는 허용합니다. @NotEmpty - // null, ""을 허용하지 않습니다. " "는 허용합니다. @NotBlank - // null, "", " " 모두 허용하지 않습니다. @Email - // 이메일 형식을 검사합니다. 다만 ""의 경우를 통과 시킵니다. @Email 보다 아래 나올 @Patten을 통한 정규식 검사를 더 많이 사용합니다. @Pattern(regexp..