Backend

들어가며 캐시에 저장을 했지만 자주 히트율이 떨어지는 데이터의 경우 캐시에서 데이터를 찾는 작업, 디비에서 데이터를 조회하는 작업이 이중으로 일어나며 메모리 자원을 차지하기 때문에 캐시는 상황에 맞게 설정을 해야합니다. 제가 개발한 서비스의 메인 페이지에 위치하여 자주 조회되고, 수정이 거의 일어나지 않아 히트율이 높은 해시태그 데이터와 네일샵 데이터를 캐시에 저장하여 활용하기로 결정했습니다. Global Cache vs Local Cache 캐싱처리를 하면서 크게 local cache ,global cache 2가지가 있다는 것을 알게 되었습니다. local cache 의 경우 로컬 캐시는 애플리케이션 내부에서만 유효하며, 동일한 애플리케이션 내의 여러 모듈이나 서비스 간에는 공유되지 않습니다. 또한,..
테스트의 필요성 1. Regression 잘 돌아가던 코드가 이번 배포로 인해서 동작하지 않는 상황을 Regression이라 부릅니다. 이런 것을 한 두 번 경험하다 보면, 전체적으로 수정과 배포가 무서워지게 됩니다. 2. 좋은 아키텍처를 유도 SOLID S( 단일 책임 원칙 ) : 테스트는 명료하고 간단하게 작성해야 하기 때문에, 단일 책임 원칙을 지키게 됨. 테스트가 너무 많아져서 이게 무슨 목적의 클래스인지 눈에 안 들어오는 지점이 생김. 이때가 클래스를 분할해야 하는 시섬, 그러면서 책임이 자연스럽게 분배됨. O ( 개방 폐쇄 원칙 ) : 테스트 컴포넌트와 프로덕션 컴포넌트를 나눠 작업하게 되고 필요에 따라 이 컴포넌트를 자유자재로 탈부착이 가능하게 개발하게 됨 L ( 리스코프 치환 원칙 ) : ..
들어가며 지금까지 프로젝트에선 레이어드 아키텍처를 사용하여 유사한 기능들을 같은 계층으로 묶어 Controller, Service, Repository를 추상화 없이 바로바로 사용하였습니다. JpaRepository 가 인터페이스로 만들어지긴 했지만 사실상 JPA에 직접 의존하고 있기 때문에 JPA와 강결합이 되어있습니다. 따라서 이번 프로젝트에서는 의존성 역전을 해주었습니다. 시스템 외부 연동 ( DB, WebClient 등)은 가능하면 모두 추상화하여 구현해 주었습니다. 일단 Repository interface를 새로 만들어서 분리해 주었습니다. 이것은 JPA와 관계없는 인터페이스입니다. 그리고 Persistence Layer에 해당 인터페이스의 구현체를 둡니다. 그 구현체는 Jpa Reposito..
이 포스팅에서는 spring security 및 jwt, Spring Data JPA 관련 내용은 다루고 있지 않습니다. RestTemplate vs FeignClient? 구글 서버, 카카오 서버와 HTTP 통신을 하기 위해선 라이브러리가 필요합니다. 처음에는 restTemplate을 사용하여 구글로그인을 구현했습니다. 하지만 카카오 로그인을 구현하는 와중에 FeignClient라는 것을 알게 되어 둘 중 무엇으로 통일할지 고민하며 특징을 비교해 보았습니다. RestTemplate REST API를 호출할 수 있는 Spring 내장 클래스입니다. Spring3.0부터 지원되었고, json, xml 응답을 모두 받을 수 있습니다. REST API 서비스를 요청 후 응답으로 받을 수 있도록 설계되어 있으며..
들어가며 우리 프로그램에서는 @RestControllerAdvice를 사용하여 모든 @RestController에서 발생하는 예외에 대하여 로그를 찍고 슬랙에 알림을 보내고 있다 대부분이 @RestControllerAdvice에서 잘 처리되나 몇몇 에러의 경우 스프링의 BasicErrorController 포맷으로 응답값이 왔다 따라서 우리 프로그램에서는 아래와 같이 두 가지 형태로 에러 메시지가 왔다 물론 모든 에러가 @RestControllerAdvice에서 처리된다면 가장 좋겠지만 BasicErrorController 에서 에러가 처리되는 경우에도 로그를 찍고 슬랙에 알림을 보내며, 오른쪽과 같은 에러 형식으로 보내주고 싶었다! 슬랙 에러 알림 관련 포스팅 https://seowoolog.tisto..
Token 인증 VS JWT 인증 DRF Token 단순한 랜덤 문자열로 각 User와 일대일 매칭 유효기간 X Token만으로 어떤 유저인지 알 수 없고 Token에 매칭된 User가 누구인지 데이터베이스에서 찾아야만 알 수 있다 JWT ( JSON Web Token ) 토큰 자체에 User 데이터를 담을 수 있어 데이터베이스를 조회하지 않아도 User 인증이 가능하다 포맷 : "헤더.내용.서명" → Header와 payload(내용) : base64인코딩 / signature(서명) : Header와 payload를 조합하고 비밀키로 서명한 후 base64 인코딩 서버에서 토큰 발급 시에 비밀키로 서명을 하고 발급 시간 및 유저 정보 등을 저장 비밀키로 서명 했기에 위조변조가 불가능 ( 비밀키를 잘 ..
DRF에서 지원하는 인증 rest_framework.authentication.SessionAuthentication 웹 프론트엔드와 장고가 같은 호스트를 쓴다면 세션 인증을 사용할 수 있다 하지만 외부 서비스/앱 ( ex. react, 안드로이드 앱)에서는 사용할 수 없다 rest_framework.authentication.BasicAuthentication 매 요청 시마다 인증을 수행한다 매번 username/password를 넘기는 것이 보안상 위험하다 rest_framework.authentication.TokenAuthentication 매 요청 시마다 인증을 수행한다 초기에 username/password로 Token을 발급받고, 이 Token을 매 API 요청에 담아 보내 인증 처리 Tok..
Throttling이 필요한 이유 자신이 자신만의 API 서버를 만들고 클라이언트를 만들었을 때는 필요없을 수 있는 기능이다 그러나, 만약 오픈 API 서비스를 한다면 다른 개발자나 유저에 대해서 호출 횟수를 제한할 필요가 있다 기본 사용 용어 Rate : 지정 기간 내에 허용할 최대 호출 횟수 Scope : 각 Rate에 대한 별칭 Throttle : 최대 호출 횟수를 넘은지를 판단하는 로직이 구현된 클래스 기본 제공 Throttle AnonRateThrottle 인증된 요청 : 제한X 비인증된 요청 : IP 단위로 횟수 제한 디폴트 scope : 'anon' → anon라는 이름으로 rate를 지정 UserRateThrottle 인증된 요청 : 유저 단위로 횟수 제한 비인증된 요청 : IP 단위로 횟..
DRF에서 기본 지원하는 페이징 방식 PageNumberPagination : page , page_size 인자를 통한 페이징 처리 LimitOffsetPagination : offset, limit 인자를 통한 페이징 처리 PageNumberPagination page_size 미지정 상황을 위해, 디폴트 지정이 필요 # settings.py REST_FRAMEWORK = { "PAGE_SIZE" : 10, } 특정 APIView에서 page_size을 custom 하게 지정 ← PageNumberPagination 상속받아 page_size 설정 from rest_framework.pagination import PageNumberPagination class MyPageNumberPaginatio..
Filtering 목록조회 APIView에서는 조건에 따른 필터링이 필요 ex. QuerySet의 filter/exclude 필터링에 의한 인자 참조 APIView @api_view self.request.user self.request.user self.request.GET self.request.GET self.request.query_params(GET과 동일) request.query_params (GET과 동일) self.kwargs 함수의 키워드 인자 Generic Filtering / Ordering SearchFilter → search_fields (반드시 필요) 하나의 속성 참조 search_fields 기본(아무것도 쓰지X) : 포함된 문자열 search ex. search_field..
dltjdn
'Backend' 카테고리의 글 목록