Java

[어드민 페이지 만들기] Request, Response (with API 명세)

15호의 개발자 2022. 3. 17. 12:00
반응형

[어드민 페이지 만들기] Request, Response (with API 명세)

 

 

이제부터는 각 서비스를 직접 만들어가면서 데이터 부분(json 바디 부분)이 어떤식으로 생성되고, DB를 조회해봄으로써 어떤식으로 만들어지는지 확인해보자. 이전까지는 기본적인 부분을 다뤄봤다면 이제부터는 실질적인 서비스 로직을 개발한다.

 


 

1. Request

 

사용자 API중에 생성에 해당하는 create를 봐보자. 아래 api 명세서에 나와있듯이 json 바디에 들어갈 데이터를 받아줄 준비를 해야한다.

 

[Create] API 문서_Request

 

해당 request를 받아주기 위해, network 패키지 하위에 request 패키지를 하나 만든다. 앞으로 요청(request)에 해당하는 클래스는 모두 여기에 만들 것이다.

 

위 API 문서에서 공통 부분에 해당하는 통신시간(transactionTime)을 제외한 data 부분에 해당하는 변수들을 UserApiRequest 클래스에 작성한다. api 문서에서는 스네이크 케이스를 사용하지만 JAVA에서는 카멜 케이스를 사용한다는 것도 까먹으면 안 된다.

 

UserApiRequest

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserApiRequest {

    private Long id;

    private String account;

    private String password;

    private UserStatus status;

    private String email;

    private String phoneNumber;

}

 

아직까지는 create 단계이므로 가입일자(registered_at)나 해지일자(unregistered_at) 같은 경우는 클라이언트단에서 받는 게 아니라 서버에서 받는 값이기 때문에 생략하도록 한다.

 

 

 

2. Response

 

[Create] API 문서_Response

 

위 API 명세서는 Request가 들어오면 해당 데이터를 처리하고 이러이러한 정보를 내려주겠다는 것을 정리해놓은 문서이다.

 

network 패키지 하위에 response 패키지를 하나 만든 후, UserApiResponse 클래스를 하나 만들어서 공통 부분(통신시간, 응답코드, 비고)을 제외한 data 부분을 정의해보자.

 

UserApiResponse

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserApiResponse {

    private Long id;

    private String account;

    private String password;

    private UserStatus status;

    private String email;

    private String phoneNumber;

    private LocalDateTime registeredAt;

    private LocalDateTime unregisteredAt;

}

 

헤더 부분(공통 부분)은 지난 시간에 작성을 해놨고, 여기서는 data 부분만 내려줄 예정이다. 참고로, password는 당연히 마스킹 되어서 내려갈 것이다.

 

 

 

 

request와 response 클래스를 비교해보면 거의 비슷한 내용인데,
왜 굳이 두 개로 나눠서 작성하는가?

 

password를 예로 들어 보겠다. 요청을 할 때는 password가 평문으로 들어갈 것이지만, response로 내려줄 때는 암호화해서 처리할 것이다. 이처럼 같은 값들을 다르게 정의해서 내려주는 경우가 있으므로 클래스를 따로 나눠서 관리하는 것이다.

 

 


 

이제 다시 controller로 가보자. UserApiController와 CrudInterface는 지난 글(클릭!)을 참고하면 된다.

 

UserApiController

@RestController
@RequestMapping("/api/user")
public class UserApiController implements CrudInterface<UserApiRequest, UserApiResponse> {

    @Override
    @PostMapping("")    // /api/user
    public Header<UserApiResponse> create(@RequestBody Header<UserApiRequest> request) {
        return null;
    }
    
    @Override
    @GetMapping("{id}") // /api/user/{id}
    public Header<UserApiResponse> read(@PathVariable(name = "id") Long id) {
        return null;
    }
    
    @Override
    @PutMapping("") // /api/user
    public Header<UserApiResponse> update(@RequestBody Header<UserApiRequest> request) {
        return null;
    }
    
    @Override
    @DeleteMapping("{id}")  // /api/user/{id}
    public Header delete(@PathVariable Long id) {
        return null;
    }
    
}

 

컨트롤러를 다음과 같이 수정한다. Header에 UserApiResponse가 내려갈 것이고, 요청에 대해서는 UserApiRequest를 받는다.

 

 

CrudInterface

import com.example.study.model.network.Header;

public interface CrudInterface<Req,Res> { // 반드시 작성해야할 부분을 이렇게 인터페이스로 만듦

    Header<Res> create(Header<Req> request);

    Header<Res> read(Long id);

    Header<Res> update(Header<Req> request);

    Header delete(Long id);

}

CrudInterface도 수정해야 한다. 위와 같이 Req와 Res를 제네릭으로 받도록 수정한다. request를 받아올 때는 항상 Header를 달고 오기 때문에 파라미터는 Header<Req>로 설정해둔다. (참고: Header class)

 

 

 

 Req와 Res로 지정한 이유는?

 

UserApiRequest와 UserApiResponse가 아닌 Req와 Res로 지정한 이유는, User 말고도 Item, Order 등 앞으로 만들어야 할 컨트롤러들이 많기 때문이다. User라고 콕 집어서 제네릭을 설정하면 이를 다 포함할 수 없기 때문에, 다른 컨트롤러도 동일하게 상속받을 수 있게끔 Req와 Res로 설정해놓는다.

 

 


 

 

 

(출처: 패스트캠퍼스 Java & SpringBoot로 시작하는 웹 프로그래밍)

반응형