-
[스프링 인 액션] Chapter 7 - REST 서비스 사용하기 :: Traverson으로 REST API 사용하기개발서적읽기/Spring in Action 제 5판 2020. 8. 25. 16:37
Traverson은 스프링 데이터 HATEOAS에 같이 제공되며 스프링 애플리케이션에서 하이퍼미디어
API를 사용할 수 있는 솔루션이다. 이것은 자바 기반의 라이브러리이며, 같은 이름을 갖는
유사한 기능의 자바스크립트 라이브러리로부터 영감을 얻은 것이다.
Traverson은 '돌아다닌다'는 의미로 붙여진 이름이며, 여기서는 관계 이름으로 원하는 API를
이동하며 사용할 것이다. Traverson을 사용할 때는 우선 해당 API의 기본 URI를 갖는 객체를
생성해야 한다.
Traverson traverson = new Traverson(
URI.create("http://localhost:8080/api"), MediaTypes.HAL_JSON);여기서는 Traverson을 타코 클라우드의 기본 URL로 지정하였다. Traverson에는 이 URL만
지정하면 되며, 이후부터는 각 링크의 관계 이름으로 API를 사용한다. 또한, Traverson
생성자에는 해당 API가 HAL 스타일의 하이퍼링크를 갖는 JSON 응답을 생성한다는 것을
인자로 지정할 수도 있다. 이 인자를 지정하는 이유는 수신되는 리소스 데이터를 분석하는
방법을 Traverson이 알 수 있게 하기 위해서다. 어디서든 Traverson이 필요할 때는
Restemplate처럼 Traverson 객체를 생성한 후에 사용하거나 또는 주입되는 빈으로 선언할 수
있다.
Traverson 객체가 생성되었으므로 이제는 링크를 따라가면서 API를 사용할 수 있다.
예를 들어, 모든 식자재 리스트를 가져온다고 해보자. 각 ingredients 링크들은 해당 식자재
리소스를 링크하는 href 속성을 가지므로 그 링크를 따라가면 된다.
ParameterizedTypeReference<Resources<Ingredient>> ingredientType =
new ParameterizedTypeReference<Resources<Ingredient>>() {};
Resources<Ingredient> ingredientRes =
traverson
.follow("ingredients")
.toObject(ingredientType);
Collection<Ingredient> ingredients = ingredientRes.getContent();이처럼 Traverson 객체의 follow()를 호출하면 리소스 링크의 관계 이름이 ingredients인
리소스로 이동할 수 있다. 이 시점에서 클라이언트는 ingredients로 이동했으므로 toObject()를
호출하여 해당 리소스의 콘텐츠를 가져와야 한다.
toObject()의 인자에는 데이터를 읽어 들이는 객체의 타입을 지정해야 한다. 이때 고려할 것이
있다. Resources<Ingredient> 타입의 객체로 읽어 들여야 하는데, 자바에서는 런타임 시에
제네릭 타입의 정보(여기서는 <Ingredient>)가 소거되어 리소스 타입을 지정하기 어렵다.
그러나 ParameterizedTypeReference를 생성하면 리소스 타입을 지정할 수 있다.
만일 이것이 REST API가 아닌 웹사이트의 홈페이지였다고 하자. 그리고 REST 클라이언트 코드가
아닌 브라우저를 사용해서 해당 홈페이지를 본다고 하자. 그러면 식자재를 알려주는 페이지의
링크를 보게 될 것이고 이 링크를 클릭하여 따라갈 것이다. 그리고 그다음 페이지가 나타나면
해당 페이지를 읽을 것이다. 이것은 Traverson을 사용해서 Resources<Ingredient> 객체로
해당 콘텐츠를 가져오는 것과 유사하다.
다음은 조금 더 흥미로운 사용 예로, 가장 최근에 생성된 타코들을 가져온다고 하자. 이때는
다음과 같이 홈 리소스에서 시작해서 가장 최근에 생성된 타코 리소스로 이동할 수 있다.
ParameterizedTypeReference<Resources<Taco>> tacoType =
new ParameterizedTypeReference<Resources<Taco>>() {};
Resources<Taco> tacoRes =
traverson
.follow("tacos")
.follow("recents")
.toObject(tacoType);
Collection<Taco> tacos = tacoRes.getContent();여기서는 tacos 링크 다음에 recents 링크를 따라간다. 그러면 최근 생성된 타코 리소스에
도달하므로 toObject()를 호출하여 해당 리소스를 가져올 수 있다. 여기서 tacoType은
ParameterizedTypeReference 객체로 생성되었으며, 우리가 원하는 Resources<Taco> 타입이다.
follow()는 다음과 같이 두 개 이상의 관계 이름들을 인자로 지정하여 한번만 호출할 수 있다.
Resources<Taco> tacoRes =
traverson
.follow("tacos", "recents")
.toObject(tacoType);지금까지 보았듯이, Traverson을 사용하면 HATEOAS가 활성화된 API를 이동하면서 해당 API의
리소스를 쉽게 가져올 수 있다. 그러나 Traverson은 API에 리소스를 쓰거나 삭제하는 메서드를
제공하지 않는다. 이와는 반대로 RestTemplate은 리소스를 쓰거나 삭제할 수 있지만 API를
이동하는 것은 쉽지 않다.
따라서 API의 이동과 리소스의 변경이나 삭제 모두를 해야 한다면 RestTemplate과 Traverson을
함께 사용해야 한다. Traverson은 새로운 리소스가 생성될 링크로 이동할 때도 사용할 수 있으며
이동한 다음에는 해당 링크를 RestTemplate에 지정하여 우리가 필요한 POST, PUT, DELETE 또는
다른 HTTP 요청도 할 수 있다.
예를 들어, 새로운 식자재를 타코 클라우드 메뉴에 추가하고 싶다면, 다음의 addIngredient()
처럼 Traverson과 RestTemplate을 같이 사용해 새로운 Ingredient 객체를 API에 POST하면 된다.
public Ingredient addIngredient(Ingredient ingredient) {
String ingredientsUrl = traverson
.follow("ingredients")
.asLink()
.getHref();
return rest.postForObject(ingredientsUrl,
ingredient,
Ingredient.class);
}'개발서적읽기 > Spring in Action 제 5판' 카테고리의 다른 글
[스프링 인 액션] Chapter 8 - 비동기 메시지 전송하기 :: 카프카 사용하기 (0) 2020.09.18 [스프링 인 액션] Chapter 8 - 비동기 메시지 전송하기 :: RabbitMQ와 AMQP 사용하기 (1) 2020.09.16 [스프링 인 액션] Chapter 7 - REST 서비스 사용하기 :: RestTemplate으로 REST 엔드포인트 사용하기 (0) 2020.08.25 [스프링 인 액션] Chapter 6 - REST 서비스 생성하기 :: 데이터 기반 서비스 활성화하기 (0) 2020.08.20 [스프링 인 액션] Chapter 6 - REST 서비스 생성하기 :: 하이퍼미디어 사용하기 (2) 2020.08.18 댓글