loose
이로운 개발하기
loose
전체 방문자
오늘
어제
  • 전체 (207)
    • ☕ Java (24)
    • 📘 Effective Java (9)
    • 🍃 Spring (48)
    • 📖 ORM (9)
    • ☸️ Kubernetes (13)
    • 🐧 Linux (5)
    • 🐋 Docker (5)
    • 🛠️ CI & CD (7)
    • 🕸️ Web (6)
    • 🔗 Distributed System (3)
    • 📜 Js (10)
    • 📈 Database (11)
    • 🗂️ Etc (34)
    • 🧑 Chitchat (11)
    • 📒 문학 (11)
    • 👜 개인 공부 창고 (1)

공지사항

반응형

최근 글

최근 댓글

loose
🍃 Spring

ResponseEntity의 사용법 및 유지보수

🍃 Spring

ResponseEntity의 사용법 및 유지보수

2023. 2. 20. 18:59
반응형

ResponseEntity를 쓰는 이유

일반적으로 Controller에서 아래와 같이 객체를 Return 하는 경우 HTTP 응답을 제어할 수가 없습니다.

 

@GetMapping("/")
public User getUser() {
    User user = userService.getUser();
    return user;
}

 

하지만 REST API로 만든다면 클라이언트와 서버 간의 통신에 필요한 정보를 제공해야 합니다.

그럴 때 ResponseEntity를 사용한다면 적절한 상태 코드와 응답 헤더 및 응답 본문을 생성해서 클라이언트에 전달할 수 있습니다.

 

사용 방법은 아래와 같습니다. 성공을 의미하는 OK(200 code)와 함께 user 객체를 Return 하는 코드입니다.

@GetMapping("/")
public ResponseEntity<User> getUser() {
	User user = userService.getUser();
	return ResponseEntity.ok(user);
}

 

ResponseEntity를 잘 쓰는 방법

Return은 생성자보다는 빌더 패턴 사용

생성자 패턴

return new ResponseEntity(body, headers, HttpStatus.valueOf(200));

빌더 패턴

return ResponseEntity.ok()
	.headers(headers)
	.body(body);

ResponseEntity.ok()는 정적 팩토리 메서드입니다.

그리고 뒷부분을 메소드 체이닝으로 연결한 빌더 패턴을 사용하는 것이 의미가 더 직관적이고 유지보수에 좋습니다.

ResponseEntity의 Body 타입을 명시하라

public ResponseEntity getUser() {

위와 같이 메소드를 작성하면 ResponseEntity의 타입을 작성하지 않은 것이라 Object(모든 자바의 부모 클래스)를 Return으로 받습니다.

 

위의 코드는 아래의 코드와 기능적으로 의미가 같습니다.

public ResponseEntity<Object> getUser() {

ResponseEntity의 타입은 명시하지 않으면 Object 타입을 Return 해줍니다.

다만 대부분의 상황에서는 유지보수를 위해 타입을 명시해 주는 것이 직관적이므로 좋습니다.

 

타입을 여러 개 받고 싶다면 Return 타입은 Object 대신 와일드카드 사용

반환 타입이 명확하지 않아도 Return 된다

public ResponseEntity<Object> getUsers() {
    List<User> users = userService.getUsers();
    return ResponseEntity.ok(users);
}
public ResponseEntity<?> getUsers() {
    List<User> users = userService.getUsers();
    return ResponseEntity.ok(users);
}

보통 타입을 여러개 받고 싶은 경우 아래와 같이 Object나 와일드카드를 사용할 수 있습니다.

이러한 방법은 개발 구성원들끼리 공유될 경우 개발 생산성을 높일 수 있기 때문에 좋은 선택이 될 수 있습니다.

둘 모두 사용 가능하지만 Return 할 때 객체의 타입이 명확하지 않을 때는 Object를 사용하는 것보다 와일드카드를 사용하는 것이 좋습니다.

정해지지 않은 타입을 반환한다는 점에서는 Object나 와일드카드나 같은 기능을 하지만 와일드카드를 사용하면 반환할 수 있는 객체의 타입이 명확하지 않아도 사용이 가능합니다.

 

예시로는 아래와 같습니다.

@GetMapping("/users")
public ResponseEntity<?> getUsers() {
    List<?> users = userService.getUsers();
    return ResponseEntity.ok(users);
}

와일드카드, Object vs 사용자 객체

와일드카드나 Object를 이용해서 API를 만든다면 해당 API를 사용하는 사용자는 불필요한 형변환 작업을 해줘야 하는 단점이 존재합니다.

 

아래는 (List<User>)로 불필요한 형변환을 하는 예제입니다.

public ResponseEntity<Object> getUsers() {
    List<User> users = userService.getUsers();
    return ResponseEntity.ok(users);
}
ResponseEntity<Objects> response = restTemplate.getForEntity("/users", Objects.class);
List<User> users = (List<User>) response.getBody();

그래서 와일드카드가 아닌 타입 파라미터를 사용한다면 컴파일 타임에 자동 형변환이 되므로 개발자는 따로 형변환을 해줄 필요가 없습니다.

@GetMapping("/")
public ResponseEntity<T> getUser() {
    T user = userService.getUser();
    return ResponseEntity.ok(user);
}

 

하지만 API 설계 측면에서는 타입 파라미터를 이용하는 것보다 명시적으로 사용자 객체를 지정해 주는 것이 더 좋습니다.

@GetMapping("/users")
public ResponseEntity<User> getUser() {
    User user = userService.getUsers();
    return ResponseEntity.ok(user);
}

 

객체를 명시적으로 쓰는 것이 해당 라이브러리를 사용하는 개발자들한테 더 직관적으로 보이기 때문에 어떻게 사용하는지 더 직관적입니다.

 

하지만 하나의 프로젝트 내에 구성원들끼리만 사용하는 개발이라면 와일드카드를 사용해서 개발하는 것이 생산성이 더 올라갈 수 있습니다.

각각의 방식은 어떤 목적을 가지고 있느냐에 Trade-Off가 존재하기 때문에 각각 장단점이 있습니다.

 

결론적으로 API를 제공하는 형태라면 타입은 항상 명시적으로 작성하는 것이 좋고 개발 구성원들끼리 단일 프로젝트를 설계한다면 와일드카드로 전체 타입을 받는 형태로 개발하는 것이 생산성에 더 이로울 수 있습니다.

물론 단일 프로젝트라 하더라도 규모가 크다면 와일드카드가 좋지 않은 선택이 될 수도 있겠습니다.

 

 

 

 

 

 

 

728x90

'🍃 Spring' 카테고리의 다른 글

Spring AOT(Ahead-Of-Time) 경험 이야기  (2) 2023.03.11
Spring 6.0 HTTP Interface 사용법 및 REST API Client 방식의 변화  (0) 2023.03.09
Spring WebFlux & Kotlin 샘플 프로젝트  (0) 2023.01.15
어노테이션의 요소는 항상 상수여야 하는가?(컴파일 타임 상수)  (0) 2022.12.31
스프링 로그인 권한 검사에 대한 설계 방법  (0) 2022.12.26
  • ResponseEntity를 쓰는 이유
  • ResponseEntity를 잘 쓰는 방법
  • Return은 생성자보다는 빌더 패턴 사용
  • ResponseEntity의 Body 타입을 명시하라
  • 타입을 여러 개 받고 싶다면 Return 타입은 Object 대신 와일드카드 사용
  • 와일드카드, Object vs 사용자 객체
'🍃 Spring' 카테고리의 다른 글
  • Spring AOT(Ahead-Of-Time) 경험 이야기
  • Spring 6.0 HTTP Interface 사용법 및 REST API Client 방식의 변화
  • Spring WebFlux & Kotlin 샘플 프로젝트
  • 어노테이션의 요소는 항상 상수여야 하는가?(컴파일 타임 상수)
loose
loose
불만하는 사람은 90명, 해결하는 사람은 9명, 리드하는 사람은 1명
음악과 낭만을 좋아합니다.
hELLO. 티스토리 스킨을 소개합니다.
제일 위로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.