윤개발
Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(7) - 회원가입 API 생성 본문
Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(7) - 회원가입 API 생성
DEV_SJ 2020. 11. 15. 23:23이번 포스팅에서는 User의 Controller, Service, Repository 를 생성하고 회원가입 API를 만들어보겠습니다.
먼저 JpaRepository를 상속받는 UserRepository를 생성합니다.
JPARepository를 상속받으면 기본적인 CRUD는 자동생성되며 메소드 이름으로 쿼리를 만들 수 있습니다.
package com.board.My.Board.repository;
import com.board.My.Board.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
이처럼 껍데기만 만들어도 기본적인 save, find, update, delete를 사용할 수 있습니다.
다음으로 UserService를 생성합니다.
package com.board.My.Board.service;
import com.board.My.Board.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
}
@RequiredArgsConstructor 어노테이션을 통해 UserRepository를 받습니다.
이 어노테이션은 초기화 되지않은 final 필드나, @NonNull 이 붙은 필드의 생성자를 생성해 줍니다.
주로 의존성 주입(Dependency Injection) 편의성을 위해서 사용되곤 합니다.
@Autowired 없이 의존성 주입이 가능합니다.
마지막으로 UserController를 생성합니다.
package com.board.My.Board.controller;
import com.board.My.Board.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequiredArgsConstructor
@ResponseBody
public class UserController {
private final UserService userService;
}
UserRepository와 마찬가지로 UserService를 final 필드로 등록합니다.
이로써 가장 기본적인 파일만 생성한 상태가 되었으며
이전 포스팅에서 설명한 구조에 맞게 Controller -> Service -> Repository 의 구조가 되었습니다.
이제 새로운 User를 등록하는 API를 추가해보겠습니다.
사전 작업으로 프론트에서 회원가입 정보를 받는 UserForm DTO를 생성합니다.
package com.board.My.Board.dto;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
@Getter
@Setter
public class UserForm {
@NotEmpty(message = "이메일은 필수 입니다.")
@Size(max = 100, message = "이메일은 100자리를 초과할 수 없습니다.")
private String email;
@NotEmpty(message = "이름은 필수 입니다.")
@Size(max = 20, message = "이름은 20자리를 초과할 수 없습니다.")
private String userName;
@NotEmpty(message = "비밀번호는 필수 입니다.")
@Size(max = 100, message = "비밀번호는 100자리를 초과할 수 없습니다.")
private String password;
}
@NotEmpty와, @Size 어노테이션을 통해 dto내용을 검증하고 검증 실패시 에러를 던져줍니다.
코드단에서 직접 null , size를 체크하면 코드가 길어지므로 어노테이션을 통해 검증하는 것입니다.
다음으로 동일 이메일 가입을 방지하기 위해 이메일을 가진유저가 존재하는지 확인하는 메소드를 UserRepository에 추가합니다.
public interface UserRepository extends JpaRepository<User, Long> {
boolean existsByEmail(String email);
}
어플리케이션 실행시점에 JPA가 메소드 이름을 보고 위의 쿼리를 만들어줍니다. 쿼리가 틀렷다면 런타임에러가 발생하며 어플리케이션이 실행되지 않습니다.
다음으로 중복이메일 가입시 던질 예외를 exception 패키지에 추가합니다.
package com.board.My.Board.exception;
public class DuplicateEmailException extends RuntimeException {
}
이처럼 예외로 처리하고 하나의 클래스에서 모든 예외를 처리하면됩니다.
아직 생성하지 않았지만 모든 예외를 처리하는 곳은 이전포스팅의 에러처리 부분(Exception Handler)입니다.
이제 User에 생성자 및 정적 팩토리 메소드를 추가합니다.
생성자를 바로 호출하지 않는 이유는 정적팩토리 메소드 링크를 눌러보시면 알수 있습니다.
public User(){}
public User(UserForm userForm) {
this.email = userForm.getEmail();
this.userName = userForm.getUserName();
this.password = userForm.getPassword();
}
public static User createUser(UserForm userForm){
return new User(userForm);
}
빈 User 생성자는 JPA에서 필요로 하기때문에 추가하였습니다.
이제 UserService에 다음과 같이 추가합니다.
@Transactional
public void signUpUser(UserForm userForm) throws Exception {
validateDuplicateEmail(userForm.getEmail());
userRepository.save(User.createUser(userForm));
}
private void validateDuplicateEmail(String email) throws Exception {
if(userRepository.existsByEmail(email)){
throw new DuplicateEmailException();
}
}
유저를 회원가입하는 메소드를 생성하고 이메일 중복을 체크합니다.
이메일이 중복이라면 예외를 던지며 없을시 가입을 시키는 코드입니다.
Insert 쿼리가 작동되기 때문에 @Transactional을 붙였습니다.
마지막으로 UserController에 아래 코드를 추가합니다.
@PostMapping("/signup")
public void signUpUser(@RequestBody @Valid UserForm userForm) throws Exception {
userService.signUpUser(userForm);
}
@RequestBody를 통해 userForm을 JSON으로 받고 @Valid를 통해 값을 검증합니다.
API 구성이 완료되었으니 Swagger 라이브러리를 이용하여 손쉽게 api를 호출해보겠습니다.
pom.xml에 swagger를 추가해줍니다.
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
그리고 인텔리제이 상단 오른쪽에 뜨는 메이븐 새로고침을 눌러줍니다.
변경된 pom.xml을 인식하여 의존성을 추가해줍니다.
다음으로 SwaggerConfiguration을 추가해줍니다.
package com.board.My.Board.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfiguration {
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(swaggerInfo()).select()
.apis(RequestHandlerSelectors.basePackage("com.board.My.Board.controller"))
.paths(PathSelectors.any())
.build()
.useDefaultResponseMessages(false);
}
private ApiInfo swaggerInfo() {
return new ApiInfoBuilder().title("Spring API Documentation")
.description("웹 개발시 사용되는 서버 API에 대한 연동 문서입니다")
.license("").licenseUrl("").version("1").build();
}
}
.apis의 경로는 Controller 패키지가 존재하는 경로로 변경해줍니다.
이제 Application을 실행시키고 https://locahost:8080/swagger-ui.html 에 접속합니다.
그러면 로그인창이 뜨게되는데 Spring Security의 기본설정이 되어있어 그렇습니다.
pom.xml에서 시큐리티부분을 잠깐 주석처리하고 위와 마찬가지로 메이븐 새로고침을 합니다.
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
메이븐을 새로고침하고 프로젝트를 재실행하면 아래와 같이 SwaggerUI가 나타나게됩니다.
이제 잘 동작하는지 확인하기 위해 userForm에 값을 넣고 회원가입을 진행해보겠습니다.
{
"email": "yoon@kt.com",
"password": "1234",
"userName": "yoon"
}
값을 넣고 아래 Try it out!을 클릭합니다.
그러면 Spring boot console에서 아래와 같이 로그가 나옵니다.
Hibernate: insert into user (email, password, user_name, user_id) values (?, ?, ?, ?)
중복 회원이 방지되는지 보기위해 한번 더 클릭을 해봅니다.
그럼 아래와 같이 아까 만들었던 예외가 나오게됩니다.
com.board.My.Board.exception.DuplicateEmailException: null
아직 예외처리를 완벽히 하지않아 500에러가 나오는 모습입니다.
실제 DB에도 값이 잘 들어가 있는지 확인해봅니다.
이로써 회원가입 API 작성이 완료되었습니다.
전체 코드는 아래 링크에서 확인할 수 있습니다.
https://github.com/sungjaeyoon/board
'프로젝트 > Vue.js, Spring 게시판' 카테고리의 다른 글
Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(8) - 에러처리 구현 (4) | 2020.11.20 |
---|---|
Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(6) - 백엔드API Domain 생성 (2) | 2020.10.25 |
Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(5) - 백엔드API 구조 알아보기 (0) | 2020.10.09 |
Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(4) - Intelij 설정 (4) | 2020.10.04 |
Vue.js + Spring Boot + MySQL+JPA 게시판 만들기(3) - 프론트 생성 (1) | 2020.07.29 |