인프런 커뮤니티 질문&답변

terecal님의 프로필 이미지
terecal

작성한 질문수

[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발

HTTP Status Code 제어

유저 정보 입력 컨트롤러 로직의 Http Status Code 제어에 대해 질문

작성

·

1.6K

0

    @PostMapping("/users")
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = service.save(user);
        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(savedUser.getId())
                .toUri();
        return ResponseEntity.created(location).build();
    }

에서  URI 객체 location을 이용해 return 값을 아래와 같이 설정하는데요

return ResponseEntity.created(location).build() 

질문1

uri를 만들때 사용한 ServletUriComponentsBuilder 클래스는 무슨 클래스인지 URI location 객체는 url 주소를 말하는게 맞나여?

질문2
ResponseEntity는 무슨 객체인지  뭘 created하는 건지 location인자는 왜 넘기는건지  뭘 build 해서 리턴하는건지 잘이해가 안가요 좀더 자세하게 설명해주시면 감사여 

질문3
그리고 response body에 success: true 같은걸 응답하도록 하는게 맞지 않나여? 그러려면 어떻게 해야 되나여?

질문4
그리고 user 한명 입력인데 url을 왜 /users로 하신건가요? 

질문5

그리고 dao 계층과 서비스 계층을 분리할수도 있는거죠?

답변 2

5

Dowon Lee님의 프로필 이미지
Dowon Lee
지식공유자

안녕하세요, 이도원입니다. 

요청하신 질문에 대한 답변 드립니다. 

1. ServletUriComponentsBuilder는 사용자 요청에 따른 작업을 처리한 다음, 결과 값을 토대로 관련 URI를 생성해 주는 역할을 하게 됩니다. 예를 들어, 보기와 같이 /users 등록 작업을 요청했으니, 등록이 성공한 다음에는 클라이언트에게 성공 여부와 상세정보 페이지에 대한 URI 값을 전달하기 위해 URI 객체를 생성하는데 사용됩니다. 그리고 생성된 URI 객체는 클라이언트의 response header 또는 response body에 포함하여 전달하 수 있습니다.

2. ResponseEntity 반환 객체를 생성해 줍니다. created() 메소드는 반환 객체에 대한 response 타입을 결정하는데, created로 할 경우 201 코드를 반환해 줍니다. 201 코드는 POST 요청과 같이 서버의 리소스를 추가했을 때에 대한 응답 코드이며, 201 응답 코드를 클라이언트 단에서 받게 되면, 정상 처리 되었다는 것을 알수 있게 됩니다. 굳이 success: ok와 같은 형식의 데이터를 받아서 처리할 필요가 없게 됩니다. 불필요한 네트워크 트래픽도 감소 됩니다. 그리고 location의 URI 는 response header를 보면 참조할 수 있습니다. 따라서, 클라이언트 단에서 POST 요청에 대한 성공을 인지한 다음, 다음과 같은 주소를 확인하면, 상세정보 URI을 요청할 수도 있게 됩니다.

3. success: true 같은 값으로 전달하시려면, Response.ok()로 반환하시면서, 직접 반환 객체를 생성하시면 됩니다. JSONObject또는 String으로 해도 될것 같습니다. 다만 String일 경우, 클라이언트 단에서 문자열로 된 JSON 데이터에 대한 변환 작업이 필요할 수 있습니다.

4. RESTful API를 설계할 때 복수형으로 설계하도록 권장합니다. 단일 객체만을 위한 URI이 아니라, USERS라는 데이터 리소스에 새로운 목록의 데이터를 추가하기 위한 API이기 때문입니다. https://restfulapi.net/resource-naming/

5. 네 맞습니다. 분리하는 것이 좋습니다. DAO 계층이 다른 것으로 변경되거나 할때에도, 종속성을 최소화 시킬 수 있습니다. 

감사합니다.

1

terecal님의 프로필 이미지
terecal
질문자

답변 감사합니다.

1.ServletUriComponentsBuilder 를 이용해 URI 객체를 생성한뒤 그걸 응답에 이용하는 이유?

답변) ServletUriComponentsBuilder는 사용자 요청에 따른 작업을 처리한 다음, 결과 값을 토대로 관련 URI를 생성해 주는 역할을 하게 됩니다. 예를 들어, 보기와 같이 /users 등록 작업을 요청했으니, 등록이 성공한 다음에는 클라이언트에게 성공 여부와 상세정보 페이지에 대한 URI 값을 전달하기 위해 URI 객체를 생성하는데 사용됩니다. 그리고 생성된 URI 객체는 클라이언트의 response header 또는 response body에 포함하여 전달하 수 있습니다.클라이언트의 response header 또는 response body에 포함하여 전달하 수 있습니다.

2. 응답을 return ResponseEntity.created(location).build(); 이렇게 하는 이유?

답변) ResponseEntity 반환 객체를 생성해 줍니다. created() 메소드는 반환 객체에 대한 response 타입을 결정하는데, created로 할 경우 201 코드를 반환해 줍니다. 201 코드는 POST 요청과 같이 서버의 리소스를 추가했을 때에 대한 응답 코드이며, 201 응답 코드를 클라이언트 단에서 받게 되면, 정상 처리 되었다는 것을 알수 있게 됩니다. 굳이 success: ok와 같은 형식의 데이터를 받아서 처리할 필요가 없게 됩니다. 불필요한 네트워크 트래픽도 감소 됩니다. 그리고 location의 URI 는 response header를 보면 참조할 수 있습니다. 따라서, 클라이언트 단에서 POST 요청에 대한 성공을 인지한 다음, 다음과 같은 주소를 확인하면, 상세정보 URI을 요청할 수도 있게 됩니다.

3.그리고 response body에 success: true 같은걸 응답하도록 하는게 맞지 않나여? 그러려면 어떻게 해야 되나여?

success: true 같은 값으로 전달하시려면, Response.ok()로 반환하시면서, 직접 반환 객체를 생성하시면 됩니다. JSONObject또는 String으로 해도 될것 같습니다. 다만 String일 경우, 클라이언트 단에서 문자열로 된 JSON 데이터에 대한 변환 작업이 필요할 수 있습니다.

4. 그리고 user 한명 입력인데 url을 왜 /users로 하신건가요? 

RESTful API를 설계할 때 복수형으로 설계하도록 권장합니다. 단일 객체만을 위한 URI이 아니라, USERS라는 데이터 리소스에 새로운 목록의 데이터를 추가하기 위한 API이기 때문입니다. https://restfulapi.net/resource-naming/

5. dao 와 서비스 계층이 분리되는것이 좋나여?
분리하는 것이 좋습니다. DAO 계층이 다른 것으로 변경되거나 할때에도, 종속성을 최소화 시킬 수 있습니다. 

terecal님의 프로필 이미지
terecal

작성한 질문수

질문하기