@GetMapping("/users")
public ResponseEntity<UserPageRes> users(
@RequestParam("page") @NotNull @PositiveOrZero int page,
@RequestParam("size") @NotNull @Positive int size){
// ...
}
스프링에서 @GetMapping
이용하여 API 로직을 구성할 때 쿼리 스트링에 포함되는 파라미터들의 경우 위와 같이 이름을 기반으로 매칭하여 처리할 수 있다. 사실 기본적으로 @GetMapping
을 사용하면 파라미터들을 쿼리 스트링에서 탐색하기 때문에 위 예시 코드에서 @RequestParam
은 생략 가능하다.
하지만 만약에 받아야 할 파라미터들이 많아 위와 같이 작성하였을 때 코드가 너저분해지는 문제는 어떻게 해결할 수 있을까?
불변한 객체로, 단순히 값의 집합을 캡슐화하여 나타낼 때 주로 사용한다. 값의 불변성을 보장하는 데 초점이 맞춰져 있는 객체이다.
@GetMapping("/users")
public ResponseEntity<UserPageRes> users(UserPageReq request){ ... }
@Getter
@AllArgsConstructor
public class UserPageReq {
@NotNull
@PositiveOrZero
private int page;
@NotNull
@Positive
private int size;
}
요청 파라미터들을 저장할 VO를 정의하고 위와 같이 코드를 작성하면 자동으로 필드 이름을 기반으로 파라미터들을 매핑하여 처리해준다.
앞서 VO를 활용하여 쿼리 파라미터를 처리한 API를 swagger를 활용하여 명세하기 위해 다음과 같이 UserPageReq
필드들에 @Parameter
를 활용하여 코드를 작성하였다.
package com.example.springallinoneproject.team;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class UserPageReq {
@Parameter(
name = "page",
description = "페이지 번호",
example = "1"
)
@NotNull
@PositiveOrZero
private int page;
@Parameter(
name = "size",
description = "페이지 사이즈(한 페이지당 데이터 수)",
example = "10"
)
@NotNull
@Positive
private int size;
}
이어서 API 로직에도 명세를 해주었다.
@Operation(
summary = "사용자 목록 조회",
description = "사용자 목록을 조회할 수 있습니다."
)
@ApiResponse(
responseCode = "200",
description = "사용자 목록 조회 성공"
)
@GetMapping("/users")
public ResponseEntity<UserPageRes> users(UserPageReq request){
// ...
}
하지만 위와 같이 코드를 구성하면 swagger-ui 상에서 UserPageReq
의 필드들을 파라미터 형태로 요청할 수 있게 표시되지 않는다. 이는 @ParameterObject
어노테이션을 활용하면 아주 간단하게 해결할 수 있다.
@Operation(
summary = "사용자 목록 조회",
description = "사용자 목록을 조회할 수 있습니다."
)
@ApiResponse(
responseCode = "200",
description = "사용자 목록 조회 성공"
)
@GetMapping("/users")
public ResponseEntity<UserPageRes> users(
@ParameterObject UserPageReq request){
// ...
}
참고 사항으로 쿼리 파라미터중 /users?age=10,12
형태로 요청되는 파라미터를 명세하고 싶다면 @Parameter
의 explode
속성을 Explode.FALSE
로 설정해주면 된다. 다만, swagger-ui 상에서 테스트 요청을 수행할 때는 기본적으로 Explode.TRUE
옵션으로 파라미터를 처리하기에 이 부분에 골머리를 앓을 필요는 없다.
@Getter
@AllArgsConstructor
public class UserQueryRequest {
// ...
@Parameter(
name = "age",
description = "나이 범위(하한,상한), 사용자 검색시 사용",
example = "20,25",
in = ParameterIn.QUERY,
explode = Explode.FALSE
)
private List<Integer> ages;
// ...
}