이번에는 버전관리에 대해 알아보려고 한다.
페이스북이나 카카오톡처럼 공개 API를 사용하면 어떠한 주소값을 사용하는지 먼저 알아보도록 한다.
https://developers.facebook.com/docs/graph-api/guides/versioning
페이스북이나 카카오톡 개발가이드에서 버전을 제공한다는 것을 확인해볼 수 있다.
API를 사용하는 개발자가 API 버전을 명시하는 것은 사용자에게 있어서 올바른 사용가이드를 알려주기 위해 반드시 필요하다.
REST API의 버전을 관리하는 방법은 여러가지가 있는데, 우선 URI를 통해 버전관리를 해보려고 한다.
① URI를 통한 버전관리
먼저 URI를 변경해준다.
//사용자 1명 반환 메서드
// GET /admin/users/1 -> /admin/v1/users/1
@GetMapping("/v1/users/{id}")
public MappingJacksonValue retrieveUserV1(@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");
FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo",filter);
MappingJacksonValue mapping = new MappingJacksonValue(user);
mapping.setFilters(filters);
return mapping;
}
이렇게 URI에 v1이라는 값을 넣어주고 동일한 형태로 v2도 만들어준다.
// GET /admin/users/1 -> /admin/v2/users/1
@GetMapping("/v2/users/{id}")
public MappingJacksonValue retrieveUserV2(@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");
FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfo",filter);
MappingJacksonValue mapping = new MappingJacksonValue(user);
mapping.setFilters(filters);
return mapping;
}
조금 값을 다르게 하기 위해 user 도메인을 하나 더 생성하여 진행하려 한다.
package com.example.restfulwebservice.User;
import com.fasterxml.jackson.annotation.JsonFilter;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonFilter("UserInfoV2")
public class UserV2 extends User {
private String grade;
}
User 도메인을 상속받아 UserV2도메인을 생성하고 JsonFilter의 값도 변경해준다.
UserV2에는 고객등급이라는 grade를 추가해준다.
User 클래스와 UserV2는 상속관계이므로 UserV2라는 인스턴스가 생성될 때 부모클래스를 참고해서 인스턴트가 만들어지지만 default 생성자가 존재하지 않아 오류가 발생한다.
@NoArgsConstructor를 이용하여 생성자를 생성해주면 오류가 사라진다.
다시 컨트롤러로 돌아가 코드를 살펴보면 id값을 받아오는 User 객체를 변경하면 변경할 코드 양이 많기 때문에 User를 받아와 UserV2로 변환시켜준다.
//User -> User2
UserV2 userV2 = new UserV2();
BeanUtils.copyProperties(user, userV2);
BeanUtils를 이용하여 user의 정보를 userV2로 복사해준다.
[ BeanUtils란? ]
BeanUtils란 스프링 프레임워크에서 제공해주는 Bean들간의 작업들을 도와주는 Util이다.
인스턴스를 만들수도 있고, copy도 할 수 있다.
// GET /admin/users/1 -> /admin/v2/users/1
@GetMapping("/v2/users/{id}")
public MappingJacksonValue retrieveUserV2(@PathVariable int id){
User user = service.findOne(id);
if(user == null){
throw new UserNotFoundException(String.format("ID[%s] not found",id));
}
//User -> User2
UserV2 userV2 = new UserV2();
BeanUtils.copyProperties(user, userV2); //id, name, joinDate, password, ssn
userV2.setGrade("VIP");
SimpleBeanPropertyFilter filter
= SimpleBeanPropertyFilter
.filterOutAllExcept("id","name","joinDate","grade");
FilterProvider filters = new SimpleFilterProvider().addFilter("UserInfoV2",filter);
MappingJacksonValue mapping = new MappingJacksonValue(userV2);
mapping.setFilters(filters);
return mapping;
}
서버를 재시작하고 포스트맨에서 확인을 해보면
라는 다른 버전의 정보들을 확인해볼 수 있다.
'프로그래밍 > SPRING BOOT' 카테고리의 다른 글
[인프런 : spring-boot] HATEOAS 적용 (0) | 2022.09.02 |
---|---|
[인프런 : spring-boot] REST API Version 관리 (2) (0) | 2022.09.02 |
[인프런 : spring-boot] 프로그래밍으로 제어하는 Filtering (1) | 2022.09.01 |
[인프런 : spring-boot] XML format / 데이터 제어 Filtering (0) | 2022.09.01 |
[인프런 : spring-boot] 다국어 처리를 위한 Internationalization (0) | 2022.09.01 |