1) 어떤 Request에 대해서 Response를 받는 구조를 만들어야 함.
따라서 어떤 User정보를 받아서 그것에 대한 create Request를 한다고 하면
Create메소드에 Mapping되어 있는 주소에 Post로 RequestBody로 싸서 보내면 생성해주고 Response를 내려주는 기능.
Request 와 Response 클래스를 따로따로 관리하는 이유는
예를 들어 비밀번호 1234에 대한 정보를 요청 할 때
Request는 비밀번호 그대로에 대해 요청 하지만
Response로 받을 때는 어떠한 처리가 반영된다던지 하는 식의 차이가 존재 하므로 따로따로 관리한다.
편의성을 돕기 위해 CRUD에 대한 인터페이스를 만들어 놓음.
public interface CrudInterfase<Req,Res> {
Header<Res> create(Header<Req> request);
Header<Res> read(Long id);
Header<Res> update(Header<Req> request);
Header delete(Long id);
}
a) Header작성
어떠한 Entity에 대한 요청에 대해서도 정보를 내려주는 역할을 하는 객체
모든 Entity에 공통적으로 들어가는 header 부분과 Entity에 따라 달라지는 data부분으로 나뉘어 짐.
data는 따라서 제너릭 타입으로 명시.
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Header<T>{
//api 통신 시간
private LocalDateTime transactionTime;
//api 응답 코드
private String resultCode;
//api 부가 설명명
private String description;
//변하는 부분은 제너릭으로 표현현
private T data;
//정상적 연결 OK
public static <T> Header<T> OK(){
return (Header<T>)Header.builder()
.transactionTime(LocalDateTime.now())
.resultCode("OK")
.description("OK").build();
}
//Data 존재시 DataOK
public static <T> Header<T> OK(T data){
return (Header<T>)Header.builder().
transactionTime(LocalDateTime.now()).
resultCode("OK").
description("OK").
data(data).build();
}
//비정상 ERROR
public static <T> Header<T> ERROR(String description){
return (Header<T>)Header.builder()
.transactionTime(LocalDateTime.now())
.resultCode("ERROR")
.description(description)
.build();
}
}
Header에는 연결이 정상적으로 설정되었을 때와 데이터가 존재하고 연결이 설정되었을 때, 그리고 비정상적인 상황
3가지에 대해서 값을 반환해주는 메소드가 존재 한다.
b) Request , Response 객체를 만듬.
<Request>
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserApiRequest {
private Long id;
private String account;
private String password;
private String status;
private String email;
private String phoneNumber;
//creat와 update는 클라이언트에서 받는게 아니고 서버 단이기 때문에 생략
}
<Response>
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserApiResponse {
private Long id;
private String account;
private String password;
private String status;
private String email;
private String phoneNumber;
private LocalDateTime registeredAt;
private LocalDateTime unregisteredAt;
//Response는 등록 후에 내려오는 것이므로 registered에 대한 정보가 있음.
}
c) 해당 Entity의 Api controller 를 만들어서 각각의 메소드에 해당하는 주소를 mapping 해 준다.
@Slf4j
@RestController
@RequestMapping("/api/user")
public class UserApiController implements CrudInterfase<UserApiRequest,UserApiResponse> {
@Autowired
private UserApiLogicService userApiLogicService;
@Override
@PostMapping("") // /api/user
public Header<UserApiResponse> create(@RequestBody Header<UserApiRequest> userApiRequest) {
log.info("{}",userApiRequest);
return userApiLogicService.create(userApiRequest); // Service와 Controller를 연결 시켜 줌.
}
@Override
@GetMapping("{id}") // /api/user/{id}
public Header<UserApiResponse> read(@PathVariable Long id) {
return null;
}
@Override
@PutMapping("") // /api/user
public Header<UserApiResponse> update(@RequestBody Header<UserApiRequest> userApiRequest) {
return null;
}
@Override
@DeleteMapping("{id}") // /api/user/{id}
public Header delete(@PathVariable Long id) {
return null;
}
}
4) 해당 Entity의 각 메소드에 대한 service를 구현 한다.
@Service
public class UserApiLogicService implements CrudInterfase<UserApiRequest, UserApiResponse> {
@Autowired
private UserRepository userRepository;
// 1. request data 가져오기
// 2. user 생성
// 3. 생성된 데이터 -> UserApiResponse 만들어서 return
@Override
public Header<UserApiResponse> create(Header<UserApiRequest> request) {
//1. request data
UserApiRequest userApiRequest = request.getData();
//2. User 생성 -> Repository로 DB에 저장 목적.
User user = User.builder()
.account(userApiRequest.getAccount())
.password(userApiRequest.getPassword())
.status("REGISTERED")
.phoneNumber(userApiRequest.getPhoneNumber())
.email(userApiRequest.getEmail())
.registeredAt(LocalDateTime.now())
.build();
User newUser = userRepository.save(user);
//3 .생성된 데이터 -> userApiResponse return
return response(newUser);
}
@Override
public Header<UserApiResponse> read(Long id) {
return null;
}
@Override
public Header<UserApiResponse> update(Header<UserApiRequest> request) {
return null;
}
@Override
public Header delete(Long id) {
return null;
}
private Header<UserApiResponse> response(User user)
{
//user -> userApiResponser
UserApiResponse userApiResponse = UserApiResponse.builder()
.id(user.getId())
.account(user.getAccount())
.password(user.getPassword())
.email(user.getEmail())
.phoneNumber(user.getPhoneNumber())
.status(user.getStatus())
.registeredAt(user.getRegisteredAt())
.unregisteredAt(user.getUnregisteredAt())
.build();
// Header + data -> return
return Header.OK(userApiResponse);
}
}
//User를 받아서 Response로 반환 해 주는 함수 작성.
private Header<UserApiResponse> response(User user)
{
//user -> userApiResponser
UserApiResponse userApiResponse = UserApiResponse.builder()
.id(user.getId())
.account(user.getAccount())
.password(user.getPassword())
.email(user.getEmail())
.phoneNumber(user.getPhoneNumber())
.status(user.getStatus())
.registeredAt(user.getRegisteredAt())
.unregisteredAt(user.getUnregisteredAt())
.build();
// Header + data -> return
return Header.OK(userApiResponse);
//OK를 static으로 한 이유 -> 이렇게 바로 쓰기 위해서.
}
'Spring' 카테고리의 다른 글
@PathVariable (0) | 2019.11.14 |
---|---|
서버와 Java 연동 Case변경 (0) | 2019.11.14 |
@Builder, @Accessors (0) | 2019.11.14 |
@Configuration , @Create~ , @LastModified~ (0) | 2019.11.14 |
연관 관계 설정. (0) | 2019.11.12 |