이 글은 스프링이 제공하는 빌더 클래스를 통해 보다 편리하고 가독성 높게 클래스 속성을 정의하는 방법을 알아봅니다.
외부 API를 요청할 때 우리는 해당 API 경로를 적고 파라미터를 작성하는 등 Url을 작성해주어야합니다.
WebClient
나 FeginClient
를 사용하면 이미 자체적으로 빌더나 매핑 방법을 제공하여 편리합니다.
하지만 RestTemplate
은 그러한 편의방법을 제공하지 않습니다. 만약 특정 API의 get요청을 보낼 시 다음과 같이 작성해주어야합니다.
public String getFoo(String fooId) {
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> params = new HashMap<>();
params.put("id", fooId);
params.put("isFoo", true);
return restTemplate.getForObject("https://fooapi.com/{id}?isFoo={isFoo}", String.class, params);
}
보다시피 경로와 파라미터 변수를 직접 작성해서 바인딩해야하므로 조금 귀찮습니다.
이럴 경우 스프링이 제공하는 Url 빌더인 UriComponentsBuilder
를 사용할 수 있습니다.
public String getFoo(String fooId) {
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject(
UriComponentsBuilder.fromHttpUrl("https://fooapi.com/{id}") // 1
.queryParam("isFoo", true) // 2
.build(fooId) // 3
.toUriString(), // 4
String.class);
}
fromHttpUrl
메소드로 호스트와 경로를 넘겨 빌더 작성을 시작합니다.queryParam
메소드로 파라미터를 작성합니다.build
메소드로 url의 변수를 바인딩합니다.toUriString
메소드로 url 문자열을 완성시킵니다.그 외 UriComponentsBuilder
에서 여러 메소드를 제공하니 한번 살펴보시기 바랍니다.
RestTemplate
은 현재 유지보수만 지원하고 스프링 진영에선 WebClient
사용을 강권하지만 여전히 많은 프로젝트에서 RestTemplate
을 사용합니다.
RestTemplate
을 사용할 때 보통 빈으로 등록해 전역에서 사용하거나 직접 생성하는 사용하는 경우도 있습니다.
빈으로 사용하는 것은 요청하는 API가 하나라면 문제가 없겠지만 여러게하면 해당 API의 기본 헤더라던가 필수 파라미터 등 각 API만의 조건을 충족시킬 수 없어 결국 빈으로 등록한 RestTemplate
을 복제하여 사용하거나 직접 생성하기 마련입니다.
이럴 때 RestTemplateBuilder
을 사용하면 좀 더 편리하게 RestTemplate
을 생성할 수 있습니다.
public class FooApiProvider {
private final RestTemplate restTemplate;
public FooApiProvider(RestTemplateBuilder restTemplateBuilder) { // 1
restTemplate = restTemplateBuilder
.rootUri("https://fooapi.com") // 2
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // 3
.defaultHeader("userid", "fooId")
.build(); // 4
}
...
}
FooApiProvider
클래스의 생성자입니다. 생성 시 RestTemplateBuilder
를 인자로 받아 final 변수인 restTemplate
를 초기화해줍시다.RestTemplate
의 기본 url을 지정해줍니다. 지정해주면 요청 시 나머지 경로만 작성해줘도 됩니다.build
메소드로 RestTemplate
를 생성합니다.그 외 RestTemplateBuilder
에서 여러 메소드를 제공하니 한번 살펴보시기 바랍니다.
Jackson
라이브러리는 스프링에서 json을 다루기 위해 기본으로 사용되는 라이브러리입니다. 그 중 ObjectMapper
로 우리는 문자열을 객체로 변환하거나 객체를 문자열로 변환합니다.
보통 json을 다룰 때 네이밍 전략을 통일하여 ObjectMapper
를 빈으로 등록해 사용하지만 기본 전략과 다르게 사용할 때는 다른 때와 같이 빈으로 등록한 ObjectMapper
을 복제하거나 직접 생성하여 사용합니다.
이 역시 스프링에서 Jackson2ObjectMapperBuilder
라는 ObjectMapper
의 빌더 클래스를 제공합니다.
public static Jackson2ObjectMapperBuilder objectMapperBuilder() {
return Jackson2ObjectMapperBuilder.json() // 1
.propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) // 2
.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES) // 3
.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // 4
.featuresToDisable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
.modules(new JavaTimeModule()); // 5
}
json()
메소드를 사용하여 빌더 클래스를 시작합니다.SNAKE_CASE
를 사용하였습니다.JavaTimeModule
을 지정했습니다.이런식으로 Jackson2ObjectMapperBuilder
을 static 메소드로 지정하거나 빈으로 등록해 전역에서 사용할 수 있게하여 각 클래스에서 재정의해 사용하도록 할 수 있습니다.
그 외 Jackson2ObjectMapperBuilder
에서 여러 메소드를 제공하니 한번 살펴보시기 바랍니다.
스프링이 제공하는 클래스를 사용한다면 해당 클래스의 빌더 클래스가 있는지 미리 확인해봅시다.
보다 편리하고 가독성 높게 클래스를 생성하여 사용할 수 있을겁니다.