Backend
9 posts
무한 스크롤 기능 구현하기 (with No Offset)

OFFSET 방식의 페이지 처리 문제점 일반적인 페이지네이션 방식은 아래와 같다. 와 명령어를 이용하면 (어디부터) LIMIT(몇개의) 데이터를 불러올지 결정한다. 이를 이용해 을 페이지 번호로 활용한다. (offset = page size * page number) OFFSET의 경우 앞에서 읽었던 행을 다시 읽기 때문에, 페이지 번호가 뒤로 갈수록 더욱 느려진다는 문제점이 있다. image https://jojoldu.tistory.com/528 만약 OFFSET이 1000이고, LIMIT이 10일 경우, 1,000부터 10개를 읽어야 하기 때문에 1,010개의 데이터를 읽는다. 즉, 뒤로 갈수록 버려야하지만 읽어야 할 데이터가 많기 때문에 느려지는 것이다. No OFFSET 페이지네이션 위 쿼리처럼 을 사용하지 않고 페이지네이션을 수행한다는 의미이다. 조회 시작 부분을 인덱스로 빠르게 찾아 첫 페이지만 읽도록 하는 방식이다. No OFFSET으로 무한 스크롤 구현하기 구현…

GlobalExceptionHandler 리팩토링

기존 코드 기존 코드의 경우 Handler에 너무 많은 책임이 있었고, 통일되지 않아 지저분한 느낌이 들었다. 위 코드만 봐도 알 수 있듯이 크기가 클수록 코드의 양이 길어지고 통일성이 사라진다. 모든 예외를 전부 처리해야하기 때문에 코드의 양이 길어지며, 확장성 역시 떨어진다. 코드 리팩토링 모든 을 처리하는 을 하나 생성한다. 해당 을 처리하는 를 생성한다. 위 코드를 통해 필요한 에러만 핸들링하도록 수정함으로써 재사용성을 높였다. 모든 예외처리 클래스가 을 상속받도록 하면, 어디서든 와 를 받을 수 있다. 위와 같이 처리함으로써 예외처리 코드 및 응답의 통일성, 확장성, 의 코드 크기를 줄일 수 있다. 향후 새로운 커스텀 오류를 처리하고 싶은 경우 을 상속받아 생성하고, 위 예시와 같이 사용하면 된다. 참고 자료 상속을 활용한 Global Exception Handler 리팩토링

(JWT) Access Token 과 Refresh Token 저장 및 관리에 대한 고민

본 포스팅에서는 프로젝트에서 채택한 JWT 를 통한 토큰 교환 방식에 대한 생각을 적어보려고 합니다. 설명하기 앞서, 간단히 JWT에 대해 알아보겠습니다. JWT 란? header typ : JWT (토큰의 종류를 지정. 이 경우 JWT로 고정) alg : 암호화 알고리즘 payload 토큰에서 사용할 정보들의 조각인, Claim 이 담겨 있다. 클레임은 JSON(Key, Value)의 형태로, 다수의 정보를 넣을 수 있다. Signature (서명) 서명은 토큰의 유효성 검증을 할 때 사용되는 곳으로, 무결성을 보장한다. 헤더 + 페이로드를 BASE64로 인코딩 한 값을 지정된 비밀 키를 이용해 헤더에 적혀있는 alg 으로 암호화한다. 서명은 데이터를 암호화 하는 것은 아니고, 토큰의 데이터가 변조 되지 않았다는 것을 보장합니다. -> 무결성 해커가 페이로드의 값을 조금이라도 바꾼다면 해시 알고리즘에 의해 Signature는 바뀔 것이고, 서버에서 해당 값을 비교해 데이터가 …

Spring Security를 이용한 인증/인가 구현

본 포스팅에서는 프로젝트에서 구현한 사용자 인증 및 인가 구현 과정을 살펴보고자 합니다. 이를 통해 회원가입, 로그인, 로그아웃 기능을 구현하였습니다. Spring Security 동작 방식 스프링 시큐리티는 애플리케이션에서 인증/인가에 대한 설정을 편리하게 할 수 있도록 도와줍니다. 위 사진은 일반적인 Spring 서버에서 요청을 처리하는 구조를 나타내는 그림입니다. 서블릿 컨테이너 안에는 서블릿에 도달하기 전에 요청을 순차적으로 처리하는 필터들의 집합인, FilterChain 이라는 것이 있습니다. FilterChain(서블릿 컨테이너) 클라이언트로부터 들어오는 모든 HTTP 요청은 일단 Servlet Container(톰캣)에 의해 처리됩니다. FilterChain은 순서대로 요청을 필터링하고 마지막 필터가 처리를 완료하면, 요청은 DispatcherServlet으로 전달됩니다. DelegatingFilterProxy Spring의 ApplicationContext에서…

Q&A 추천/비추천, Q&A 스크랩 - 바인딩 변수 사용, 쿼리문 및 로직 개선

추천/비추천 로직 개선 Q&A 추천/비추천 로직을 이전에는 아래와 같이 작성했다. 기존 추천/비추천 로직은 다음과 같다. qnaId, memberId를 이용해 추천/비추천 데이터를 findById로 받아온다. 만약 데이터가 있는 경우, 아래와 같이 데이터를 처리한다. (추천 로직 기준으로 설명한다.) , 여부를 받아온다. 만약 상태가 추천이라면, 삭제가 안 된 경우 추천 취소로 인식하고 해당 데이터를 삭제한다. 상태가 추천인데 삭제된 경우 다시 복구 시킨다. (다시 추천) 상태가 비추천인 경우, 만약 해당 데이터가 삭제되었으면 복구 후 추천 상태로 변경한다. (B → G) 데이터가 없는 경우 새로 만들어준다. 하지만 생각해보니,, 데이터를 굉장히 비효율적으로 처리한다는 생각이 들었다. 🥲 일반적으로 쿼리를 두번 사용하는 것보다 한 번에 요청하는 것이 더 효율적인 것으로 알고 있다. 그래서 고민 끝에 쿼리를 아래와 같이 수정해 로직을 개선했다. 개선한 점은 다음과 같다. , 여부…

Backend Branch Convention

Branch type 브랜치 전략은 간략한 Git flow 전략을 사용합니다. main (master) : 개발 서버 배포를 위한 브랜치 #{issue number}/name : 기능 구현을 위한 브랜치 Branch Naming 브랜치명은 반드시 소문자로만 작성해주시고, 케밥 케이스로 작성합니다. name은 스프린트를 영어로 요약하여 작성해주세요.

Backend Commit Convention

Commit Message Form 은 첫 줄 작성 후 엔터를 누르면 작성할 수 있습니다. (선택 사항) 사용 예시 Type 메세지 타입은 반드시 소문자를 사용해주세요. Type Description feat 새로운 기능 추가 시 사용합니다. fix 오류 수정 시 사용합니다. docs README.md 등의 문서 작성 및 수정 시 사용합니다. style 들여쓰기, 케이스 등 코드 스타일 변경 시 사용합니다. (ex. 카멜 케이스 → 스네이크 케이스) refactor 불필요한 코드 삭제, 코드 리팩토링 등의 전반적인 프로젝트 리팩토링 시 사용합니다. test 테스트 코드 작성 시 사용합니다. ci/cd CI/CD 설정 파일 수정 시 사용합니다. hotfix 치명적인 오류를 급히 수정할 때 사용합니다. rename 파일 이름 변경 시 사용합니다. perf 성능 개선 시 사용합니다. chore 기타 사소한 수정 시 사용합니다. Message 메세지는 ‘~다’로 끝나지 않으며, 한 줄로…

Backend Code Convention

Version Guide java version: v11 Code Style Guide 코드의 는 최대 120자를 넘지 않도록 합니다. 하나의 메소드는 하나의 역할만 수행하도록 작성합니다. 메소드의 매개변수가 4개 이상일 시 별도의 객체를 만들어 전달합니다. 코드 작성 시 스타일은 카멜 케이스로 작성해주세요. 변수는 명사형으로, 메소드(함수)는 동사형으로 작성해주세요. 자주 사용하는 혹은 불변하지 않는 값은 enum이나 final로 선언해주세요. 접근 제어, 인터페이스/구현부 분리 등의 캡슐화를 최대한 지키며 코드를 작성합니다. Backend의 경우 폴더명(패키지)은 소문자로, 파일명은 카멜 케이스로 작성해주세요. Backend의 경우 문자열 작성 시 사용해주세요. CRUD method의 경우 다음과 같은 네이밍을 사용합니다. 동작 Repository Service Create insertXXX createXXX Read findXX(ByXXAnd/OrYY) getXX(ByXXA…

Backend Issue/PR Convention

Issue Guide 각 목적에 맞는 이슈 템플릿을 사용합니다. 이슈 제목은 스프린트를 한 줄로 요약해서 작성해주세요. 라벨은 등 상황에 맞는 라벨을 달아주세요. 는 각 스프린트의 담당자를 지정합니다. PR 시 완료 라벨을 달아주시고, Merge되면 해당 이슈를 반드시 닫아줍니다. (PR에서 설정) 커밋 메세지 작성 시 반드시 이슈 번호를 달아 커밋 메세지를 해당 이슈에서 볼 수 있도록 합니다. PR Guide PR 템플릿을 사용하여 최대한 상세하게 작성합니다. PR 제목은 이슈 제목과 일치시켜주세요. 는 코드 리뷰어 및 테스터를 설정합니다. Approved 승인 없이는 절대 Merge하지 않습니다. 승인 전 반드시 오류가 없는지 테스트해주시고, 코드 컨벤션을 지켰는지 확인해주세요. Merge target은 반드시 브랜치로 지정해주세요. PR을 보내기 전 반드시 pull을 받아 최신 상태를 유지해주세요.