monorepo 프로젝트 구성 프로젝트의 디렉토를 생성해준다. mkdir typeorm-apollo-server-example yarn berry를 사용할 예정이기 때문에, 아래 명령어로 berry 버전으로 변경해준다. yarn set version berry 아래에서 apollo server를 오류없이 원활하게 구축하기 위해, .yarnrc.yml의 nodeLinker를 node-modules로 수정해준다. nodeLinker: node-modules yarnPath: .yarn/releases/yarn-3.2.3.cjs yarn init 명령어로 monorepo 프로젝트를 초기 설정한다. yarn init -y package.json이 생성이 되면, workspace 경로를 정의하고, 편의를 위해 s..
환경 nodejs: v16.15.1 (lts) yarn version: berry 프로젝트 구조: monorepo Framework: apollo-server-express 기타 사용 모듈: typescript, Knex DB: postgresql monorepo 프로젝트 생성 graphql 서버 구축 전에 yarn workspace를 활용하여 monorepo 프로젝트 생성을 한다. mkdir knex-apollo-server-example yarn berry를 사용하기 위해 버전을 변경한다. 그리고 yarn init 명령어로 프로젝트 초기 설정을 한다. yarn set version berry yarn init -y .yarnrc.yml에서 nodeLinker에 node-modules를 추가한다. no..
초기 설정 빈 프로젝트 생성 서버 구축을 위한 디렉토리 생성 $ mkdir apollo-server-test $ cd apollo-server-test yarn berry 설정 yarn berry를 사용하기 위해 yarn set version 명령어를 통해 berry로 변경해준다. $ yarn set version berry 변경 후 제대로 변경이 됐는지 확인해본다. $ yarn -v 3.2.1 Apollo Server 구축 의존성 모듈 설치 graphql 서버를 구축하기 위해, 본 글에서는 apollo-server를 사용한다. yarn berry를 사용하여, apollo-server와 graphql를 설치한다. $ yarn init $ yarn add apollo-server graphql zero-..
@RequestBody @RequestBody 는 JSON 형태의 데이터를 Java 객체에 매핑할때 사용하는 어노테이션이다. 예를 들어 아래와 같이 '공지 사항'과 관련된 글쓰기 API를 만들었다고 했을때, 비즈니스 로직은 생략 (입력받은 값 그대로 반환하도록 함) NoticeVo.java @Getter @Setter @Builder @NoArgsConstructor @AllArgsConstructor public class NoticeVo { private int id; // ID private String title; // 제목 private String contents; // 컨텐츠 private LocalDateTime registeredAt; // 등록일 } ApiNoticeController...
@Controller 어노테이션을 이용하면 기본적으로 view 페이지를 찾아서 띄어주는 역할을 한다. 하지만 REST API를 개발해야하는 상황이라면 각 메소드마다 @ResponseBody를 붙여서 데이터를 그대로 반환하도록 할 수 있다. (아래 글 참고) 2021.05.17 - [Spring] - @ResponseBody를 이용하여 데이터 반환 @ResponseBody를 이용하여 데이터 반환 보통은 @Controller 어노테이션을 이용하여 Controller 를 생성했을때, (ViewResolver에 의해) return 값으로 반환하는 문자열 이름의 view 페이지를 띄어준다. (아래 예시 코드 참고) 더보기 HelloCotroller.java.. memostack.tistory.com 하지만, 위 ..
보통은 @Controller 어노테이션을 이용하여 Controller를 생성했을때, (ViewResolver에 의해) return 값으로 반환하는 문자열 이름의 view 페이지를 띄어준다. (아래 예시 코드 참고) 더보기 HelloCotroller.java import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller public..
JPA의 Fetch Fetch는 Entity를 조회할때, 그 Entity와 연관관계가 있는 다른 Entity의 정보를 어느 시점에 가지고 오는지 결정해준다. Fetch의 타입은 2가지가 있다. LAZY Fetch Type EAGER Fetch Type LAZY Fetch Type (지연 로딩) Lazy는 '게으른'이란 뜻을 가지며, 사전 의미처럼 LAZY Fetch 타입은 실제로 엔티티 조회시에 바로 가지고 오지 않고, 연관 관계에 있는 엔티티를 참조할때 그때 가지고 온다. 예를들어, 사용자(User) 와 사용자 권한(Role) 정보를 담은 Entitiy가 있고, 2개의 Entity는 서로 1:1 관계를 이룬다고 하자 테스트 코드 @Entity @Table(name = "user") @Getter @Bu..
AOP 구현 AOP 개념은 아래 글 참고 2021.03.11 - [Spring] - Spring의 AOP 개념 (Aspect Oriented Programming) Spring의 AOP (Aspect Oriented Programming) AOP AOP는 Aspect Oriented Programming 의 약자로, 번역하면 관점 지향 프로그래밍이다. AOP는 주 비지니스 로직 앞, 뒤로 부가적인 기능을 추가하고 싶을때 사용하는데 예를들어, 로그처리, 보안처리, DB memostack.tistory.com 의존성 추가 org.springframework.boot spring-boot-starter-aop 서비스(비즈니스 로직) 구현 테스트를 위한 비즈니스 로직을 구현 AOP 구현에 집중하기 위해, 단순히..
AOP AOP는 Aspect Oriented Programming의 약자로, 번역하면 관점 지향 프로그래밍이다. AOP는 주 비지니스 로직 앞, 뒤로 부가적인 기능을 추가하고 싶을때 사용하는데 예를들어, 로그처리, 보안처리, DB 트랜잭션 처리 등이 있다 관점을 횡단으로 바꿔서 바라보는 것을 횡단 관심 사항이라 하며, 부가적인 로직을 Cross Cutting Concern, 주 비즈니스 로직을 Core Concern 이라 한다. AOP를 사용하는 이유? 코드의 중복을 줄일 수 있다. 주 업무 로직과 부가적인 로직을 분리할 수 있다. Java로 AOP 구현 AOP는 디자인 패턴 중 프록시 패턴(Proxy Pattern)을 이용해서 구현할 수 있다. 스프링에서는 어노테이션으로 더 쉽게 구현할 수 있음 성능 ..
IoC (Inversion of Control) IoC는 Inversion of Control의 약자로 한국어로 번역하는 '제어의 반전' 이라는 뜻을 가짐 재사용 라이브러리의 흐름이 반대라고 말할 수 있음 내용을 살펴보기 전에 DI(Dependency Injection)을 알고 있으면 이해하기 쉽다. 2021.03.10 - [Spring] - Spring의 DI 개념 (Dependency Injection) Spring의 DI 개념 (Dependency Injection) 객체를 생성하는 2가지 방법 객체를 생성하는 방법에는 2가지가 방법이 있다. 필요한 곳에 직접 생성하는 방법 외부에서 미리 생성해두고 필요한 곳에 할당(주입)하는 방법 위 그림은 직접 객체 memostack.tistory.com 아래 ..
객체를 생성하는 2가지 방법 객체를 생성하는 방법에는 2가지가 방법이 있다. 필요한 곳에 직접 생성하는 방법 외부에서 미리 생성해두고 필요한 곳에 할당(주입)하는 방법 위 그림은 직접 객체 생성하는 경우, 외부에서 객체 주입하는 경우를 그림으로 표현했다. 이름과 나이를 받는 Member 객체와 그 객체를 사용하는 MemberUse 클래스를 표현함 직접 객체를 생성하는 경우 위 그림에서 만약 1년이 지나 '홍길동'이 29살에서 30살이 되었다고 했을때, 모든 객체를 다 수정해줘야하는 번거로움이 있다. // Member public class Member { private String name; private int age; public Member(String name, int age) { this.nam..
dependency 추가 mvnrepository.com/artifact/io.jsonwebtoken/jjwt/0.9.1 ... io.jsonwebtoken jjwt 0.9.1 ... JWT 토큰 생성하기 JwtManager라는 Bean을 생성한다. 공통으로 쓸것이기 때문에 IoC에 담아두고 써도 무관 import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.stereotype.Component; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class JwtManager {..
REST API 테스트 Rest API를 테스트할 때는 @WebMvcTest 어노테이션을 사용한다. MockMvc를 생성할때는 MockMvcBuilders를 사용하여 생성한다. 다른 방법으로 MockMvcBuilders를 사용하지 않고, MockMvc에 @Autowired를 사용하여 자동으로 생성하여 주입할 수 있다. @ExtendWith(SpringExtension.class) @WebMvcTest(MemberController.class) @DisplayName("MemberController 테스트") class MemberControllerTest { private MockMvc mvc; @MockBean private MemberService memberService; @BeforeEach pu..
서비스 작성 MemberService.java 생성자 주입을 통해, MemberRepository와 BCryptPasswordEncoder를 주입한다. BCryptPasswordEncoder는 시큐리티에 Bean을 생성했다. (아래 펼쳐서 확인) 더보기 @Configuration @EnableWebSecurity @EnableGlobalAuthentication public class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 비밀번호 암호화 인코딩 방식 정의 * * @return BCryptPasswordEncoder BCrypt 단방향 암호화 */ @Bean public BCryptPasswordEncoder passwordEncoder..
사전 준비 테스트를 위해, Entitiy와 Repository를 생성한다. Entity 생성 Role.java @Entity @Table(name = "role") @Getter @Builder @NoArgsConstructor @AllArgsConstructor(access = AccessLevel.PROTECTED) @ToString public class Role { // PK @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; // 권한 이름 @Column(nullable = false, length = 50) private String roleName; } Repository 생성 RoleRepository.java ..
엔티티에서는 java의 boolean을 사용하고, Database에서는 Y 또는 N으로 처리하고 싶을때, @Converter 어노테이션을 사용하여 해결할 수 있다. 컨버터 객체 생성 BooleanToYNConverter.java @Converter public class BooleanToYNConverter implements AttributeConverter { /** * Boolean 값을 Y 또는 N 으로 컨버트 * * @param attribute boolean 값 * @return String true 인 경우 Y 또는 false 인 경우 N */ @Override public String convertToDatabaseColumn(Boolean attribute) { return (attrib..
실행환경 SpringBoot Maven adoptopenjdk1.8 dependency 추가 version 1.4.197을 사용한다. 최근 버전에서는 SpringBoot를 실행하면서 보안상의 이유로 database를 생성하지 못하도록 막아놓아서, 먼저 DB를 생성하고 실행해야하는 번거로움이 있다. 어차피 실제로 서비스할때는 h2 DB는 테스트용으로 사용할 예정이므로, 1.4.197 버전 (예전 버전)을 사용한다. ... com.h2database h2 1.4.197 runtime ... application.yaml 설정 application.properties로 해도 상관없으나, 본 글에서는 yaml 파일로 설정 spring: h2: console: enabled: true datasource: pla..
Spring Security를 추가하고 아무런 설정을 안하면, Security가 모든 요청을 가로챈 다음 /login 경로로 리다이렉트한다. 그래서, 아래와 같은 화면이 나온다. Spring Security의 기본 계정 정보 테스트를 위해서 로그인을 해보고 싶다면, 아래계정으로 접속한다. username: user password: (콘솔 창에 나온 비밀번호, 예시: 7aa1e310-2a4b-46a7-85fb-7883d18b72ef)
목표 간단한 로그인 기능을 구현 Spring Security 를 사용 JPA와 MySQL을 사용 Mustache 템플릿 엔진 사용 MySQL 설치 MySQL 설치는 본 글에서는 다루지 않는다. 아래글 참고 2020/10/30 - [Database/RDB] - MySQL 설치하기 (Mac OSX) MySQL 설치하기 (Mac OSX) MySQL 설치 본 글에서는 Homebrew 를 이용하여 MySQL 을 설치한다. $ brew update $ brew install mysql 만약, 특정 버전을 따로 설치하고 싶다면 아래 명령어를 수행한다. 그리고, 원하는 버전의 mysql을 설치한.. memostack.tistory.com Spring Project 생성 start.spring.io/에서 메이븐 프로젝트..
REST API 규격에 따라 일반적으로 CamelCase가 아닌 snake_case를 사용한다. 각각의 멤버 변수에 @JsonProperty를 적용하여 바꿔줄 수도 있지만, 설정파일을 이용해서 전체 프로젝트에 적용 할 수 도 있다. 방법 1. @JsonProperty 멤버 변수에 @JsonProperty 어노테이션을 붙여서 snake_case로 변경할 수 있다. class User { @JsonProperty("user_id") private String userId; } 방법 2. application.properties (또는 application.yaml) 설정 '방법 1'을 이용하면 매번 변수를 생성 할때마다 어노테이션을 추가해야하는 버거로움이 있다. Spring 설정파일에 spring.jacks..