회원서비스를 Microservice로 구성하기
기능들은 전부 postman으로 조회가 가능하도록 RestController 기반으로 작성됨.
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
instance:
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
...
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/user-service/**
# MySQL 설정하기
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/DB명
username: 계정 이름
password: 계정 비밀번호
driver-class-name: com.mysql.cj.jdbc.Driver
spring:
jpa:
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
show-sql: true
Entity와 DTO 간의 차이점은 엔티티는 기본키가 필수이고, DTO는 상관없다는 점이다.
DTO는 Entity 내부 데이터를 은닉하기 위해 대리로 데이터를 전송하기 위한 클래스이다.
생성자
public ResponseFindUserDto(User user){
this.userId = user.getUserId();
this.id = user.getId();
this.email = user.getEmail();
this.name = user.getName();
this.uuid = user.getUuid();
}
build.gradle 의존 추가 : Bean Validation 의존성
@Valid 어노테이션 추가 - Controller 메서드 매개변수
@Valid 어노테이션 사용 시, 해당 객체가 유효성 검사를 통과해야만 메서드가 실행되도록 한다.
직렬화 : 객체 -> JSON / 역직렬화 : JSON 데이터 -> 객체
@RestController
public class RestAPIController {
@RequestMapping("/info") // @Valid가 붙으면 HumanDTO에 역직렬화 전 요구된 양식대로 들어오는지 체크함.
public ResponseEntity<?> getHumanInfo(@Valid @RequestBody HumanDTO humanDTO){
return ResponseEntity.ok(humanDTO);
}
}
위의 dPwpdptj @RequestBody 어노테이션과 함께 사용되었다.
@RequestBody는 HTTP 요청 본문의 JSON 데이터를 객체로 바인딩 해준다.
만약, 유효성 검사에 실패하게 되면 Spring에서 MethodArgumentValidException 예외 발생시킨다.
유효성 검사를 하면, 데이터 무결성 보장 및 잘못된 데이터의 유입을 방지할 수 있다.
어노테이션 | 역할 및 설명 |
---|---|
@NotNull | 값이 null이 아닌지 검사합니다. |
@NotBlank | 값이 null이 아니고, 빈 문자열이 아닌지 검사합니다. |
@NotEmpty | 값이 null이 아니고, 빈 문자열 또는 빈 컬렉션이 아닌지 검사합니다. |
@Size(min, max) | 값의 길이가 주어진 범위 내에 있는지 검사합니다.(String) |
@Min(value) | 값이 주어진 최솟값 이상인지 검사합니다.(Number)) |
@Max(value) | 값이 주어진 최댓값 이하인지 검사합니다.(Number)) |
@Pattern(regexp) | 값이 정규 표현식 패턴과 일치하는지 검사합니다. |
값이 유효한 이메일 주소 형식인지 검사합니다. | |
@Future | 값이 미래의 일자인지 검사합니다. |
@Past | 값이 과거의 일자인지 검사합니다. |
@Digits(integer, fraction) | 값이 주어진 정수 및 소수 자릿수의 숫자인지 검사합니다. |
@AssertTrue | 값이 true인지 검사합니다. |
@AssertFalse | 값이 false인지 검사합니다. |
@DecimalMin(value) | 값이 주어진 최솟값 이상인지 검사합니다. (소수점 포함) |
@DecimalMax(value) | 값이 주어진 최댓값 이하인지 검사합니다. (소수점 포함) |
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
public void createUser(RequestCreateUserDto userDto){
User user = userDto.toEntity();
userRepository.save(user);
}
public ResponseFindUserDto findUserByUuid(String uuid){
User user = userRepository.findUserByUuid(uuid);
user = Optional.ofNullable(user).orElseThrow(()->{
throw new RuntimeException("가입되지 않은 회원입니다.");
});
return new ResponseFindUserDto(user);
}
}
public interface UserRepository extends JpaRepository<User,Long> {
User findUserByUuid(String uuid);
}
@RequestMapping("user-service")
@RestController
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("health-check")
public String healthCheck(){
return "server is available";
}
/*
@RequestBody : JSON 형태로 값을 받아올 때 사용.
*/
@PostMapping("users")
public ResponseEntity<String> createUser(@Valid @RequestBody RequestCreateUserDto requestCreateUserDto){
userService.createUser(requestCreateUserDto);
return ResponseEntity.ok("회원 가입 완료!");
}
@GetMapping("users/{uuid}")
public ResponseEntity<ResponseFindUserDto> getUser(@PathVariable String uuid){
ResponseFindUserDto user = userService.findUserByUuid(uuid);
return ResponseEntity.ok(user);
}