본 포스팅은 인프런 - Spring Boot를 이용한 RESTful Web Service 개발 강의를 바탕으로 공부하고 정리한 글입니다.
스프링 부트가 제공하는 Filtering 기법을 이용해 전달하고자 하는 응답 데이터 값을 제어하는 방법을 알아보도록 하자.
아래는 간단한 사용자 관리 Rest API 예제 소스 코드이다.
해당 예제 소스 코드를 바꿔가며 차근차근 알아보도록 하자.
👉🏻 사용자 도메인 객체
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private Date joinDate;
private String password;
private String ssn;
}
👉🏻 사용자 서비스
@Service
public class UserDaoService {
private static List<User> users = new ArrayList<>();
private static int usersCount = 3;
static {
users.add(new User(1, "Anne", new Date(), "pass1", "701010-111111"));
users.add(new User(2, "Jolly", new Date(), "pass2", "801010-222222"));
users.add(new User(3, "Alice", new Date(), "pass3", "901010-222222"));
}
public List<User> findAll() {
return users;
}
public User findOne(int id) {
for (User user : users) {
if (user.getId() == id) {
return user;
}
}
return null;
}
}
👉🏻 사용자 컨트롤러
@RestController
@RequiredArgsConstructor
public class UserController {
private final UserDaoService service;
@GetMapping("/users")
public List<User> retrieveAllUsers() {
return service.findAll();
}
@GetMapping("/users/{id}")
public User retrieveUser(@PathVariable int id) {
User user = service.findOne(id);
if (user == null) {
throw new UserNotFoundException(String.format("ID[%S] not found", id));
}
return user;
}
}
전체 사용자 조회 API에 대한 포스트맨 테스트 결과이다.
사용자 도메인 객체의 모든 필드값이 응답 데이터로 전달되는 것을 확인할 수 있다.
만약 사용자의 password, ssn 정보에 대해서는 전달하고 싶지 않다면 어떻게 할까?
이럴 경우 스프링 부트가 제공하는 Filtering 기법을 이용해 처리할 수 있다!
@JsonIgnore
👉🏻 사용자 도메인 객체
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private Date joinDate;
@JsonIgnore
private String password;
@JsonIgnore
private String ssn;
}
응답 데이터로 전달하고자 하지 않는 필드에 대하여 @JsonIgnore 어노테이션을 붙혀주면 된다.
포스트맨 테스트 결과 @JsonIgnore를 붙혀준 password, ssn 정보는 전달되지 않음을 확인할 수 있다.
@JsonIgnoreProperties
👉🏻 사용자 도메인 객체
@Data
@AllArgsConstructor
@JsonIgnoreProperties(value = {"password", "ssn"})
public class User {
private Integer id;
private String name;
private Date joinDate;
private String password;
private String ssn;
}
@JsonIgnoreProperties를 클래스 단위에 붙혀주면 @JsonIgnore와 동일한 기능을 적용할 수 있다.
위와 같이 value 속성을 통해 전달하지 않고자 하는 필드를 다중 지정해줄 수 있다.
SimpleBeanPropertyFilter
👉🏻 사용자 도메인 객체
@Data
@AllArgsConstructor
@JsonFilter("UserInfo")
public class User {
private Integer id;
private String name;
private Date joinDate;
private String password;
private String ssn;
}
도메인 객체에 @JsonFilter로 필터의 이름을 지정해서 사용한다.
👉🏻 사용자 컨트롤러
@GetMapping("/users")
public MappingJacksonValue retrieveAllUsers() {
List<User> users = service.findAll();
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
.filterOutAllExcept("id", "name", "joinDate", "password");
SimpleFilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo", filter); // 필터 생성
MappingJacksonValue mapping = new MappingJacksonValue(users); // 데이터 변환
mapping.setFilters(filters); // 필터링 적용
return mapping;
}
- SimpleBeanPropertyFilter.filterOutAllExcept를 통해 필터링할 내용을 지정한다.
- SimpleFilterProvider().addFilter를 통해 사용할 필터를 생성한다.
- 필터링된 데이터 값을 반환하기 위해서는 MappingJacksonValue 객체로 변환해 반환해야 한다.
- 따라서 찾아온 사용자 데이터를 MappingJacksonValue로 변환한 다음 만들어준 필터를 적용해 반환한다.
포스트맨 테스트 결과 필터링 된 내용만 응답 데이터로 전달되는 것을 확인할 수 있다.
이 방법을 이용하면 API에 따라 각각 다른 내용의 응답 데이터를 전달할 수도 있다.
👉🏻 사용자 컨트롤러
@GetMapping("/users/{id}")
public MappingJacksonValue retrieveUser(@PathVariable int id) {
User user = service.findOne(id);
if (user == null) {
throw new UserNotFoundException(String.format("ID[%S] not found", id));
}
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter
.filterOutAllExcept("id", "name", "joinDate", "ssn");
SimpleFilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo", filter); // 필터 생성
MappingJacksonValue mapping = new MappingJacksonValue(user); // 데이터 변환
mapping.setFilters(filters); // 필터링 적용
return mapping;
}
전체 사용자 조회 API와 달리 개별 사용자 조회 API는 id, name, joinDate, ssn 내용이 필터링 되도록 했다.
그 결과 응답 데이터의 내용이 전체 사용자 조회와 다르게 구성되는 것을 확인할 수 있다.
이렇게 Response 데이터를 제어하는 방법을 간단하게 알아보았다.
'🌱 Spring > REST' 카테고리의 다른 글
REST API를 설계할 때 고려해야 할 사항 (0) | 2022.09.22 |
---|---|
Exception Handling (0) | 2022.09.06 |
HTTP Status Code 제어하기 : 201 Created 반환하기 (0) | 2022.09.06 |
REST API (0) | 2022.08.28 |