https://spring.io/guides/gs/rest-service/

  • 만들게 될 것:

https://gturnquist-quoters.cfapps.io/api/random 는 랜덤으로 인용구 데이터를 제시하는 RESTful 한 서비스 링크이다. 이번에는 RestTemplate 을 사용하여 위 링크에서 인용구를 검색하는 앱을 만들어보자.

  • 준비물:

git clone https://github.com/spring-guides/gs-consuming-rest.git 로 프로젝트를 받아오자.


REST 한 자원을 가져오기

https://gturnquist-quoters.cfapps.io/api/random 에 접속한다면 다음과 같은 형식의 데이터를 얻을 수 있다.

{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}

매우 쉬운 정보이지만 curl(client URL)이나 브라우저를 통해 접근하기에는 유용해보이지 않는다. 따라서 프로그램을 통해서 정보를 사용해야한다.

Spring 은 RestTemplate 이라는 템플릿 클래스를 제공하는데, RESTful 한 서비스들과 상호작용할 수 있게 하며, 접근된 데이터를 커스텀 도메인 타입으로 묶을 수도 있다.

먼저 데이터를 가지고 있을 도메인 클래스를 생성한다. 아래와 같이 Quote 클래스를 만들어보자.

src/main/java/com/example/consumingrest/Quote.java

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {

  private String type;
  private Value value;

  public Quote() {
  }

  public String getType() {
    return type;
  }

  public void setType(String type) {
    this.type = type;
  }

  public Value getValue() {
    return value;
  }

  public void setValue(Value value) {
    this.value = value;
  }

  @Override
  public String toString() {
    return "Quote{" +
        "type='" + type + '\'' +
        ", value=" + value +
        '}';
  }
}

@JsonIgnoreProperties 를 사용하여, 이 타입에 맞지 않는 모든 속성은 무시됨을 명시한다.

직접적으로 데이터를 커스텀 타입에 매치하려면, API 로부터 반환된 JSON 데이터의 key 와 동일한 변수명을 가져야한다. 이름이 같지 않다면 @JsonProperty 주석을 달아서 JSON 문서의 정확한 key 를 설정해야한다. 위의 코드에서는 JSON 데이터의 type 과 value 변수명을 그대로 사용하고 있다.

JSON 데이터의 value 변수는 기존 자료형으로 표현할 수 없으므로, 새 클래스를 만들어준다.

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Value {

  private Long id;
  private String quote;

  public Value() {
  }

  public Long getId() {
    return this.id;
  }

  public String getQuote() {
    return this.quote;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public void setQuote(String quote) {
    this.quote = quote;
  }

  @Override
  public String toString() {
    return "Value{" +
        "id=" + id +
        ", quote='" + quote + '\'' +
        '}';
  }
}


앱 마무리 하기

src/main/java/com/example/consumingrest/ConsumingRestApplication.java 를 다음과 같이 수정하자.

package com.example.consumingrest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class ConsumingRestApplication {

	private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);

	public static void main(String[] args) {
		SpringApplication.run(ConsumingRestApplication.class, args);
	}

	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
		return builder.build();
	}

	@Bean
	public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
		return args -> {
			Quote quote = restTemplate.getForObject(
					"https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
			log.info(quote.toString());
		};
	}
}
  • Logger : 콘솔과 같은 로그에 결과물을 보낼 Logger

  • RestTemplate : Jackson JSON 라이브러리를 사용하여 들어오는 데이터를 조작한다.

  • CommandLineRunner : RestTemplate 를 실행하여 결과적으로 인용구를 가져온다.

앱 실행하기

mvnw spring-boot:run 을 cmd 에 입력하자.

콘솔창에 다음과 같은 형식의 결과물을 확인할 수 있다. 물론 내용은 랜덤한 값이다.

2019-08-22 14:06:46.506  INFO 42940 --- [           main] c.e.c.ConsumingRestApplication           : Quote{type='success', value=Value{id=1, quote='Working with Spring Boot is like pair-programming with the Spring developers.'}}