코코코딩공부/Spring
restAssured를 이용한 restDocs 와 OAS
들어가며 요즘카페 팀 프로젝트를 진행하면서 API 명세서는 노션을 통해 관리하고 있었다. 단순하게 노션을 이용하니 최신화, 오타 등 휴먼에러들이 많이 발생하였고 API 문서화 툴을 사용해서 작업하기로 하였다. 가장 도움이 많이 되었던 것은 공식문서이다. Spring REST Docs Spring REST Docs Document RESTful services by combining hand-written documentation with auto-generated snippets produced with Spring MVC Test or WebTestClient. docs.spring.io API 문서화 도구 도구로써 RestDocs와 Swagger를 고민하였다. Swagger 러닝커브가 적고, UI가 ..
Spring Security 없이 Oauth 구현기
들어가며 이번 ‘요즘카페’ 팀 프로젝트를 진행하면서 먼저 로그인 파트를 진행하게 되었다. 우리는 프로젝트로 로컬 로그인 외에 OAuth 로그인을 진행하게 되었다. 지금까지 프로젝트를 진행하면서 로그인 기능을 진행해보지 않았기 때문에 진행해보게 되었다. OAuth 흐름 1. Get /auth/{provider} 요청 사용자가 프론트엔드 로그인을 클릭시 서버로 Redirect를 한다. 이후 요청을 받은 서버는 Provider로 authURi를 생성하여 Redirect한다. 이후 Provider는 클라이언트로 Authorization code를 받는다. 💡 클라이언트에서 바로 Provider로 요청하지 않는 이유 ClientId, clientSecret 등 공개되지 않아야 하는 정보를 서버에서만 처리를 한다면..
orElse 에서 생긴 문제 해결
들어가며 프로젝트를 진행하던 중에 로그인 -> 카페 좋아요 -> 새로고침 후 로그인 -> 좋아요 데이터 증발 하는 문제가 발생했다. 우리팀 폴로는 문제의 원인이 orElse 쪽 문제라고 알려주었다. 그래서 한번 보았다. 문제 final Member member = memberRepository.findById(memberInfo.openId()) .orElse(saveNewMemberWithAllCafes(memberInfo)); 우리의 예상은 찾은 멤버가 없어서 null 일 경우 saveNewMemberWithAllCafes(memberInfo)를 실행할 것 같았다. 근데! null이던 아니던 상관없이 saveNewMemberWithAllCafes(memberInfo)가 실행되는 것이었다!!! publ..
Repository 사용기
지금까지 Dao를 이용하여 영속성 계층과 서비스 계층 간 소통을 해왔다. 이렇다 보니 서비스 단에서 해야할 일이 많았다. 코드가 길어지고 가독성이 떨어지는 것 같아 Repository를 통해 그 역할을 분리해서 사용해보았다. Dao Dao는 Data Access Object의 약자이며 데이터에 접근하는 객체이다. Dao를 거쳐서 데이터에 접근하기 때문에 상위 계층에서는 DB의 구조, 사용법 을 몰라도 된다. Repository Repository는 흔히 저장, 검색, 조회 등의 동작을 캡슐화하는 메커니즘으로, 객체 컬렉션의 추상화 로써 표현한다. 이는 처음 보았을 때 너무 어려웠다. 내가 생각한 Repository는 다음과 같다. 내가 주문을 저장한다고 해보자. 이럴 때 주문도 저장해야하고, 주문에 사용..
도메인은 id 값을 가져도 될까 ?
처음에 나는 도메인에 ID값을 넣지 않았다. 넣지 않은 이유로는 많은 크루들이 사용하는 ID값이 DB에서 auto increment되는 값이기 때문이다. 이러한 방식은 데이터베이스나 시스템에서 도메인 개체를 관리하고 구별하는 데 유용하긴하다. 물론 도메인을 식별하기 위한 수단은 필요하다. 다만 그 수단이 DB의 ID값이여야하는 것은 아니다 라고 생각한다. 그래서 나는 객체별 고유한 식별자를 사용하고자 하였다. 다만 이 과정속에서 코드가 조금 복잡해졌기에 고민을 하게 되었다. 도메인이 ID값을 갖는다는 것은 장점 고유한 값인 ID를 통해 개체를 식별하기에 매우 유용하다. DB에서 자동으로 ID값이 증가하므로 따로 관리를 해줄 필요가 없다. 단점 결국 도메인이 db에 대해서 알고 있다. 요청을 받아 도메인을..
[Spring] Argument Resolver 내부 구경 하기
사용자가 컨트롤러의 메서드 인자값으로 임의의 값을 전달하려할 때 사용된다. Argument Resolver를 Controller 단에서 사용하면 중복 코드(HttpSession에서 세션 로드, HttpServletRequest에서 요청 url 및 ip 정보 로드 등)를 깔끔하게 처리할 수 있다. RequestMapping에 대한 매칭 (RequestMappingHandlerAdapter가 수행) 이후 Interceptor 처리되고 그 후에 Argument Resolver가 파라메터를 처리한다. 언제 사용하면 좋을까? 내가 생각한 몇가지 예시는 다음과 같다. 1. 프로덕션 코드에서 코드 구조를 드러내기 싫을 때 Ex) 암호화 -> 복호화 하는 숨기고싶은 구조가 있을 때 2. 파라메터로 받는 인자를 다르게 ..
[Spring] Dispatcher Servlet이란 ? & 미션 에서 찾아보기
dispatcher servlet 이란 front controller로 들어오는 요청에 대해 적절하게 판단하여 위임해 주는 역할을 하는 서블릿이다. 공통적인 작업을 처리 한 후에 해당 요청을 처리해야하는 컨트롤러에게 위임해준다. 장점 많은 서블릿들의 URL매핑을 위해 설정파일에 등록을 시켰어야 했지만, dispatcher servlet이 모든 요청을 처리해주고 공통 작업을 진행해줌으로써 등록없이 편리하게 사용가능하다. 컨트롤러에 구현이 되있다면 dispatcher servlet이 알아서 해준다. 디스패처 서블릿이 클라이언트의 요청을 받는다. 요청을 위임할 컨트롤러를 handler mapping이 찾는다. 요청을 컨트롤러로 위임해줄 handler adapter를 찾는다. handler adapter가 co..
[Spring] Servlet 이란 ?
서블릿이란 클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술 서블릿은 자바로 구현 된 *CGI(Common Gateway Interface 서버와 애플리케이션 간에 데이터를 주고 받는 방식 또는 컨벤션) 서블릿은 자바로 구현된 CGI라고 하기에는 규약과 프로그램은 같게 비교해서 오류가 있다. 그냥 CGI 방식이 개선된 자바로 구현된 것이 서블릿 이라고 이해하면 좋을 것 같다. 동적인 처리를 위해 CGI를 만들었다. CGI는 문제가 있었는데 요청 시 마다 프로세스를 만든다. 이 프로세스는 상대적으로 만드는데 시간과 메모리가 많이드니까 쓰레드로 바꾼다. 요청 시마다 쓰레드가 다르다면 구현체가 각각 하나씩 생기는데 이것을 싱글톤 패턴으로 만든다..
[Spring] 어떤 객체를 빈으로 등록해야 할까 ?
모든 객체를 스프링 빈으로 등록해도 괜찮은가 ? 애플리케이션의 모든 객체를 스프링 컨테이너가 관리할 필요는 없다. 그럼 어떤 객체를 스프링 빈으로 등록해야하나 ? 모든 객체를 스프링 빈으로 등록할 경우에는 메모리 사용량이 많아짐에 따라 애플리케이션의 성능에 문제가 생길 수 있다. 사실 완벽하게 생각하지는 못했지만 나의 생각은 이렇다. Thread-safe 가아니면 스프링 빈을 등록할 필요하다. 예를들어 user라는 객체는 애플리케이션 실행 중 계속해서 생성 될 수 있는데 spring bean을 등록해서 사용하면 디폴트가 싱글턴이기에 새로운 객체가 생성되지 않을 수 있다. → 빈스코프를 변경해서 사용하면 어떨까 ? (가능할 것 같기도 하다) 중간에 user라는 객체가 생성 되었다가 사용이 끝나는 객체가 존..
[Spring] Bean 이란 ?
들어가며 스프링을 사용하면서 기존 자바보다 객체 생성, 조립, 사용을 훨씬 편하게 해준다는 것을 알았고 이에 기본적으로 Bean이라는 개념이 사용된다는 것을 알았다. 하지만 Bean이 무엇인지에 대한 의문점이 있어 정리해보았다. 스프링 빈 이란 ? 빈이란 스프링 IOC 컨테이너 가 관리하는 객체이다. 빈은 Spring IoC 컨테이너에 의해 인스턴스화, 조립 및 관리되는 객체이다. 인스턴스화 된 빈은 @Autowired를 통해 의존성 주입을 받을 수 있다. 인텔리제이에서 옆에 콩처럼 표시가 되어있다면 빈등록이 되었다는 것을 의미한다. @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @..