개요
Spring Boot 4에는 Jackson 라이브러리의 버전이 3으로 올라갔다. JsonView 어노테이션을 기존 2 버전에서도 사용가능한 기술이었지만 데이터의 일부만 직렬화할 수 있는 새로운 기능이 추가되어 해당 기능을 알아보도록 하자.
JsonView가 필요한 경우
JsonView는 예를 들어 사용자 API 서비스를 개발하고 있고, 각기 다른 데이터 요구사항을 가진 여러 클라이언트에 API를 제공해야 하는 경우가 있다고 생각해 보자. 각각 모바일 APP, Web, 운영툴 등 각각의 클라이언트는 사용자 API에서 필요한 필드가 모두 다를 것이다. 모바일 APP은 간단한 사용자 정보가 필요하고, 운영툴은 사용자의 모든 정보가 필요할 것이다. JsonView를 사용하지 않고 각각의 클라이언트의 요구사항에 대하여 개발을 하려면 클라이언트 별로 DTO 객체를 선언하고, DTO를 서비스하기 위한 Controller 코드와, DTO애 대한 맵핑 코드까지 작성했야 했다.
recode UserMobileAppDTO(...) { }
recode UserWebDTO(...) { }
recode UserAdminDTO(...) { }
@GetMapping("/mobile")
UserMobileAppDTO getUserMobileAppDTO(...) {
......
return new UserMobileAppDTO(user)
}
......
위 예제처럼 클라이언트에 종류에 따라 DTO 클래스가 과도하게 증가하고 반복적인 맵핑 코드로 인하여 유지관리에 대한 어려움 또한 가지게 된다.
위 문제점을 Jackson 3의 JsonView를 사용하여 해결하는 방법에 대하여 알아보자.
Getting Started
User 조회 API
Spring Boot 4를 사용하여 프로젝트를 생성하고, 사용자 정보를 관리하는 객체를 생성한다.
record User(
int id,
String name,
int age,
int grade,
LocalDate birthday) {
}
이번 예제에서는 모바일 App, Web, Admin(운영툴) 3개의 클라이언트가 있다고 가정하고 진행하겠다.
각 클라이언트의 정보를 정의할 interface를 추가한다.
public class UserViews {
public interface MobileApp { }
public interface Web extends MobileApp { }
public interface Admin extends Web { }
}
위에서 선언한 인터페이스를 기반으로 @JsonView를 사용하여 사용자(User) 클래스의 각 변수에 노출할 정보에 대하여 지정한다.
record User(
@JsonView(Users.Mobile.class)
int id,
@JsonView(Users.Mobile.class)
String name,
@JsonView(Users.Web.class)
int age,
@JsonView({Users.Web.class, Users.Admin.class})
int grade,
@JsonView(Users.Admin.class)
LocalDate birthday) {
}
각각의 클라이언트에 사용자 정보를 제공하는 Controller 코드를 추가한다.
@RestController
@RequestMapping("/api/users")
class UserController {
private final UserService userService;
......
@GetMapping("/mobile")
@JsonView(UserViews.Mobile.class)
List<User> getMobileAppUsers(...) {
return this.userService.findAll();
}
@GetMapping("/web")
@JsonView(UserViews.Web.class)
List<User> getWebUsers(...) {
return this.userService.findAll();
}
@GetMapping("/admin")
@JsonView(UserViews.Admin.class)
List<User> getAdminUsers(...) {
return this.userService.findAll();
}
}
서버를 실행하고 /api/users/mobile, web, admin URL을 호출해 보면 @JsonView로 지정한 데이터만 API로 노출되는 것을 볼 수 있다.
User 생성 API
@JsonView를 사용하여 지정한 정보만 API로 제공한 방법처럼 사용자 정보를 입력받을 때도 @JsonView를 사용하여 필요한 정보만 서버에 전송하거나 서버에서는 필요한 정보만 입력받을 수 있다.
위에서 정의한 Mobile에 필요한 정보만 입력 받을 수 있도록 Controller 코드를 생성한다.
@PostMapping
@JsonView(UserViews.Mobile.class)
User createUser(@RequestBody @JsonView(UserViews..Mobile.class) User user) {
log.info("Received user createion request {}", user);
var createdUser = new User(user.id(), user.name(), 10, 1, LocalDate.now());
return createdUser;
}
Mobile 정보만 제공하는 클라이언트(RestClient)를 사용하여 View에 해당하는 필요한 정보만 서버로 전송할 수 있다.
void createUser() {
var user = new User(10, "igooo", 20, 1, LocalData.now());
var response = restClient.post()
.uri("/api/users")
.hint(JsonView.class.getName(), UserViews.Mobile.class)
.body(user)
.retrieve()
.body(User.class);
log.info("User: {}", user);
}
마치며
Spring Boot4는 Jackson 3을 지원하지만 기존 버전에 호환성 문제 때문에 Jackson 2와 3를 함께 사용하고 있다. 하지만 새롭게 추가된 tool.jackson 패키지에는 새롭게 추가된 JsonMapper가 포함되어 있고, 새롭게 시작하는 프로젝트에서는 Jaskson 3의 기능을 알아보고 하나씩 추가해 보도록 하자.
'dev > spring' 카테고리의 다른 글
| RestTestClient를 사용하여 Spring Rest API 테스트 작성하기 (0) | 2026.01.05 |
|---|---|
| Spring Boot 4 모듈화 (0) | 2025.12.11 |
| Spring - Path Prefix (0) | 2025.08.18 |
| Spring Framework 7.0.0 API Versioning (0) | 2025.07.31 |
| Spring Framework 7.0 - Resilience Features (회복력 기능) (2) | 2025.07.27 |