스프링, JPA 블로그 작성할거임.
객체지향과 다형성 SOLID > SOLID는 좋은 객체 지향 설계의 5가지 원칙을 모아놓은 것이다. SRP 단일 책임원칙: 한 클래스는 하나의 책임만 가진다. OCP 개방-폐쇄 원칙: 확장에는 열려있으나, 변경에는 닫혀 있어야 한다. LSP 리스코프 치환 원칙: 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다. ISP ...
서블릿 서블릿 만들기 HttpServlet을 상속(extend)받아 만든 클래스에 @WebServlet 애노테이션을 붙이면 서블릿 컨테이너에 서블릿 객체가 생성되어 저장된다. HTTP 요청 시, WAS는 request와 response 객체를 새로 만들어 해당 url에 mapping된 서블릿 객체를 호출한다. 개발자는 request 객체에서 HTTP 요청 ...
ORM Object-Relational Mapping > 객체 지향 애플리케이션과 관계형 DB의 충돌 객체에 필드가 변경되었을 때, SQL문에 변경사항이 너무 많은 문제점이 있다. 또한 객체를 관계형 디비에 저장하려 하면 복잡한 과정이 필요하다는 문제점도 있다. 그래서 지금까지는 객체를 테이블에 맞추어 모델링할 수 밖에 없었다고 한다. 이 방법은 너...
스프링 aop에 대해 아주아주 간략하게 포스팅하는 글 프록시 이전 글에서도 언급했지만, 클라이언트와 서버를 컴퓨터 개념이 아닌 요청을 주고 받는 역할로 생각해보자. 지금까지 나 혹은 우리는 주로 클라이언트가 서버에 직접 요청을 보내고 직접 요청을 처리하는 것에 익숙하다. 클라이언트와 서버의 통신 사이에 proxy 라는 대리자를 놓게 되면 어떻게 될까?...
스프링이 제공하는 ExceptionResolver 스프링 부트가 기본으로 제공하는 ExceptionResolver는 다음과 같다. 다음의 우선 순위로 HandlerExceptionResolverComposite에 등록된다. ExceptionHandlerExceptionResolver @ExceptionHandler를 처리한다. Respon...
HTTP HTTP는 클라이언트와 서버 사이에 이루어지는 요청/응답 프로토콜이다. 즉, 클라이언트와 서버 사이의 의사소통 방식이라고 생각하면 된다. HTTP는 비연결성(Connectionless)과 무상태(Stateless)라는 특성을 가진다. 비연결성은 클라이언트의 요청와 서버의 응답 이후 연결이 끊기는 성질을 의미한다. 무상태란 HTTP의 비연결적인 특성...
쿠키, 세션, JWT 쿠키, 세션, JWT는 모두 stateless한 네트워크 서버의 특징을 연결성으로 사용하기 위한 방법이다. 쿠키와 세션은 서버의 저장소에 해당 값과 매칭되는 값을 가지고 있어야 하기 때문에, 서버 자원이 많이 사용된다는 단점이 있다. 이러한 단점을 해결하기 위해 JWT가 등장했다. JWT는 토큰 자체에 유저 정보를 담아서 암호화한 토큰...
망나니 개발자님의 블로그를 참고하여 작성한 블로그입니다. 망나니 개발자님의 글을 보고 따라하면서 개인적으로 느낀 것들과 모든 과정들을 추가적으로 작성할 예정입니다. 프로젝트 생성 우선 프로젝트를 생성합니다. https://start.spring.io/ 해당 링크로 접속 후 다음과 같이 프로젝트 설정을 해주었습니다. 프로젝트 파일을 실행 후, build....
멤버십 등록 API 요구사항 나의 멤버십 등록 API 기능: 나의 멤버십을 등록합니다. 요청: 사용자 식별값, 멤버십 이름, 포인트 응답: 멤버십 ID, 멤버십 이름 Repository 계층 개발 TDD를 위해선 Repository -> Service -> Controller 순으로 구현해 나아가야 한다. Controller는 Servic...
멤버십 등록 API 요구사항 나의 멤버십 등록 API 기능: 나의 멤버십을 등록합니다. 요청: 사용자 식별값, 멤버십 이름, 포인트 응답: 멤버십 ID, 멤버십 이름 Service 계층 개발 멤버십 등록 실패 (중복 존재) 우선 사용자ID와 멤버십타입으로 이미 멤버십이 존재하여 실패하는 테스트부터 작성한다. 즉, membershipRepos...
멤버십 등록 API 요구사항 나의 멤버십 등록 API 기능: 나의 멤버십을 등록합니다. 요청: 사용자 식별값, 멤버십 이름, 포인트 응답: 멤버십 ID, 멤버십 이름 Controller 계층 개발 역시 마찬가지로 테스트 코드를 먼저 작성해야 한다. 컨트롤러는 함수 호출이 아닌 API 호출을 통해 요청을 받아 응답을 처리해야하며, 메세지 컨버...
나의 멤버십 전체 조회 API 요구사항 나의 멤버십 전체 조회 API 기능: 내가 가진 모든 멤버십을 조회한다.. 요청: 사용자 식별값 응답: {멤버십 ID, 멤버십 이름, 포인트, 가입 일시}의 멤버십 리스트 Repository 계층 개발 역시나 바로 테스트 코드 개발부터 들어간다. 만나게 될 무궁무진한 컴파일 오류를 고치면서 프로덕트 코...
나의 멤버십 상세 조회 API 요구사항 나의 멤버십 상세 조회 API 기능: 나의 1개 멤버십을 상세 조회한다. 요청: 사용자 식별값, 멤버십 ID 응답: 멤버십 ID, 멤버십 이름, 포인트, 가입일시 Repository 계층 개발 멤버십 상세 조회를 위해 레포지토리 계층에 따로 추가할 코드는 없다. 왜냐하면 멤버십 등록 API를 구현하면서...
나의 멤버십 삭제 API 요구사항 나의 멤버십 삭제 API 기능: 나의 멤버십을 삭제한다. 요청: 사용자 식별값, 멤버십 번호 응답: X Repository 계층 개발 JPARepository는 deleteById라는 메서드를 제공한다. 1개의 엔티티를 먼저 추가하고, 해당 엔티티를 삭제하는 테스트 코드를 작성해본다. 컴파일 에러도 발생하...
멤버십 포인트 적립 API 요구사항 멤버십 포인트 적립 API 기능: 나의 멤버십 포인트를 결제 금액의 1%만큼 적립한다. 요청: 사용자 식별값, 멤버십 ID, 사용금액 응답: X 기타: 고정 금액 적립 방식으로의 확장이 유연하도록 구현한다. Repository 계층 개발 Repository 계층에선 따로 개발할 것이 없다. save...
이전까지 글은 망나니 개발자님의 TDD 글을 참고하여 작성한 글이고, 지금부터는 그 프로젝트에서 내가 점점 추가하고 싶은 기능들을 추가하며 진행할 계획이다. 멤버 등록 API 요구사항 멤버 등록 API 기능: 멤버 회원가입을 진행한다. 요청: 멤버 이름, 멤버 Email, 멤버 비밀번호 응답: 멤버 id 글을 작성함에 앞서, 이미 개발을...
이번엔 로그인 기능을 구현하려한다. 로그인 기능은 세션을 통한 로그인과 JWT를 통한 로그인 두가지 모두를 구현할 예정이다. 글을 쓰기 앞서, 해당 API를 구현함에 있어, 서비스 계층은 테스트를 통과하였지만 컨트롤러 계층의 테스트는 성공하지 못했음을 공지한다. 어제 새벽엔 테스트를 통과하지 못했는데 오늘 아침에 차근차근 글을 작성하면서 왜 테스트를 통과...
이번엔 로그인 과정에서, 응답으로 쿠키에 세션값을 넣어주는 것이 아닌 ResponseBody에 토큰 값을 포함시켜서 응답하는 방식을 채택하도록 하겠다. 토큰 로그인 API 요구사항 토큰 로그인 API 기능: 토큰을 통한 로그인 기능을 구현한다. 요청: 사용자 Email, 사용자 비밀번호 응답: 사용자 이름, 사용자 Email, 토큰값 Re...
jwt를 이용할 때, 혹은 로그인 기능을 이용할 때 대부분 스프링 시큐리티를 사용하곤 한다. 스프링 시큐리티에 대한 자세한 공부를 하기 전에 filter에 대한 공부를 하고 들어가려 한다. (왜냐하면 스프링 시큐리티가 필터 체인을 이용하는 것으로 어렴풋이 알고 있다.) 필터 혹은 인터셉터를 사용해서 로그인을 한 사용자와 로그인을 하지 않은 사용자를 미리 ...
aop에 관해선 다른 글에서 설명한 바 있으니 간단하게만 설명하도록 하겠다. aop는 핵심 관심사가 아닌 공통관심사를 처리해주는 기능이다. 멤버 저장 요청을 보냈다고 생각해보자. Controller를 거쳐 Service, Repository로 갔다가 역순으로 다시 올라오면서 응답을 보낼 것이다. 이때 각 계층마다 소요되는 시간을 측정하고 싶다거나 로그를 ...
이전까지의 개발은 Membership 따로, Member 따로 진행해왔다. HttpServletRequest 헤더에 사용자 식별값이 별도로 들어있다는 가정하게 개발을 진행해 온 것이다. 그래서 헤더에 값이 없으면 BadRequest 응답을 보내도록 되어있었다. 하지만 이번에 개발할 /api/v2 에서는 헤더에 있는 토큰 값을 파싱하여 Member를 찾아내...
테스트 코드 테스트 코드,,,의 중요성을 간과한 채 개발하던 시절이 있었다. 시간도 부족했고, 테스트 코드 작성법을 또 따로 공부하기 귀찮았기 때문이다. 굳이 테스트를 하자면 Service 계층이나 Repository 계층에 관련해 짧게 짧게 테스트 코드를 작성했던 것 같다. 반면, Controller 계층은 어떻게 테스트를 해야하나 의문이었다. HTTP ...