RESTful 웹 서비스를 consume 하는 application을 생성해보겠습니다.
RestTemplate
을 사용하여 Spring Boot 랜덤 quatation을 http://localhost:8080/api/random 으로 반환하는 애플리케이션을 build 해보겠습니다.
스프링 이니셜라이저를 이용하여 Spring Web을 의존성으로 추가하고 자바 17, Gradle-Groovy, Jar 설정으로 생성했다.
프로젝트 설정이 완료되면 RESTful 서비스를 사용하는(consume) 간단한 애플리케이션을 생성할 수 있습니다.
그렇게 하려면 먼저 REST 리소스(resource) 소스가 필요합니다. 우리는 https://github.com/spring-guides/quoters
에서 그러한 서비스의 예를 제공했습니다. 해당 애플리케이션을 별도의 터미널에서 실행하고 http://localhost:8080/api/random
에서 결과에 액세스할 수 있습니다. 해당 주소는 Spring Boot에 대한 인용문을 무작위로 가져와서 JSON 문서로 반환합니다. 다른 유효한 주소로는 http://localhost:8080/api/
(모든 인용문의 경우) 및 http://localhost:8080/api/1
(첫 번째 인용문의 경우), http://localhost:8080/api/2
가 있습니다. (두 번째 인용의 경우) 등(현재 최대 10개).
웹 브라우저나 curl
을 통해 해당 URL
을 요청하면 다음과 같은 JSON 문서를 받게 됩니다.
{
type: "success",
value: {
id: 10,
quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
}
}
이는 충분히 쉽지만 브라우저나 curl
을 통해 가져올 때 별로 유용하지 않습니다.
REST 웹 서비스를 사용하는 더 유용한 방법은 프로그래밍 방식입니다. 해당 작업을 돕기 위해 Spring은 RestTemplate
이라는 편리한 템플릿 클래스를 제공합니다. RestTemplate
은 대부분의 RESTful 서비스와 한 줄의 주문으로 상호 작용합니다. 또한 해당 데이터를 사용자 정의 도메인 유형에 바인딩할 수도 있습니다.
먼저 필요한 데이터를 포함할 도메인 클래스를 만들어야 합니다. 다음 목록은 도메인 클래스로 사용할 수 있는 Quote
record 클래스를 보여줍니다.
src/main/java/guides/consumingrest/Quote.java
package guides.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public record Quote(String type, Value value) { }
이 간단한 Java 레코드 클래스에는 Jackson JSON 처리(processing) 라이브러리의 @JsonIgnoreProperties
어노테이션이 추가되어 이 유형에 바인딩되지 않은 모든 속성은 무시되어야 함을 나타냅니다.
데이터를 사용자 정의 유형에 직접 바인딩하려면 API에서 반환된 JSON 문서의 키와 정확히 동일하도록 변수 이름을 지정해야 합니다. JSON 문서의 변수 이름과 키가 일치하지 않는 경우 @JsonProperty
어노테이션을 사용하여 JSON 문서의 정확한 키를 지정할 수 있습니다. (이 예에서는 각 변수 이름을 JSON 키와 일치시키므로 여기서는 해당 주석이 필요하지 않습니다.)
내부 인용문 자체를 포함하려면 추가 클래스도 필요합니다. Value
레코드 클래스는 이러한 요구를 충족하며 다음 목록(src/main/java/guides/consumerrest/Value.java
)에 표시됩니다.
package guides.consumingrest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public record Value(Long id, String quote) { }
이니셜라이저가 자동으로 생성한 main()
메서드가 있는 클래스(src/main/java/com/example/consumingrest/ConsumingRestApplication.java
)에 아래 요소들을 추가하여 RESTful 소스 인용문을 표시할 수 있도록 합니다.
RestTemplate
RestTemplate
을 실행하고 결과적으로 quotation을 가져오는(fetch) CommandLineRunner
package guides.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.context.annotation.Profile;
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
@Profile("!test")
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://localhost:8080/api/random",
Quote.class
);
log.info(quote.toString());
};
}
}
LoggerFactory
: 로깅에 사용되는 SLF4J(Logger Facade for Java)의 Logger를 가져오는 팩토리 메서드입니다.final
로 선언된 로거는 한 번 생성되고 할당된 이후에는 변경되지 않으므로 일관성 있는 로깅 방식을 유지할 수 있습니다RestTemplate
: Spring에서 제공하는 HTTP 통신을 위한 클라이언트 라이브러리로, HTTP 요청을 보내고 응답을 받을 수 있게 해줍니다.
RestTemplateBuilder
: RestTemplate
을 생성하기 위한 빌더 클래스로, 다양한 구성 옵션을 제공하며 RestTemplate
의 인스턴스를 생성합니다.
@Bean
: Spring 애플리케이션 컨텍스트에 빈(Bean)을 추가하기 위한 어노테이션으로, 해당 메서드가 반환하는 객체를 빈으로 등록합니다.
@Profile
: Spring에서 활성화될 프로파일을 지정하는 어노테이션으로, 특정 프로파일에만 적용되는 설정을 지정할 수 있습니다.
특정한 환경 또는 프로파일에 따라 다른 빈을 로드하고 싶을 때 사용됩니다.
예를 들어, 개발용과 프로덕션용 설정을 분리하고 싶을 때 @Profile을 사용하여 각각의 프로파일에 맞는 빈을 로드합니다.
@Import
@Scope
@Scope
어노테이션을 사용하여 프로토타입(scope="prototype")이나 다른 커스텀 범위로 빈을 정의할 수 있습니다.CommandLineRunner
: Spring Boot 애플리케이션을 시작할 때 실행되는 인터페이스입니다. run
메서드를 구현하여 애플리케이션 실행 시 원하는 동작을 정의할 수 있습니다.CommandLineRunner
의 run
메서드의 args
: Java 애플리케이션을 실행할 때 전달되는 커맨드 라인 인수들을 나타내는 문자열 배열입니다.
main
메서드의 args
: Java 애플리케이션의 진입점으로, 커맨드 라인에서 전달되는 인수들을 나타내는 문자열 배열입니다. SpringApplication.run
메서드에 전달되는 인수로 사용됩니다.
마지막으로 서버 포트를 설정해야 합니다. quoters
애플리케이션은 기본 서버 포트인 8080을 사용하므로 이 애플리케이션도 동일한 포트를 사용할 수 없습니다. application.properties
(Initializr가 생성한)에 다음 줄을 추가하여 서버 포트를 8081로 설정할 수 있습니다.
server.port=8081
Gradle 또는 Maven을 사용하여 명령줄에서 애플리케이션을 실행할 수 있습니다. 필요한 모든 종속성, 클래스 및 리소스가 포함된 단일 실행 가능 JAR 파일을 빌드하고 실행할 수도 있습니다. 실행 가능한 jar을 구축하면 개발 수명 주기 전반에 걸쳐 다양한 환경 등에서 서비스를 애플리케이션으로 쉽게 제공, 버전 지정 및 배포할 수 있습니다.
Gradle을 사용하는 경우 ./gradlew bootRun
을 사용하여 애플리케이션을 실행할 수 있습니다. 또는 다음과 같이 ./gradlew build
를 사용하여 JAR 파일을 빌드한 후 JAR 파일을 실행할 수 있습니다.
java -jar target/gs-consuming-rest-0.1.0.jar
2023-12-09T19:08:31.439+09:00 INFO 12025 --- [ main] g.c.ConsumingRestApplication : Started ConsumingRestApplication in 1.932 seconds (process running for 2.51)
2023-12-09T19:08:31.786+09:00 INFO 12025 --- [ main] g.c.ConsumingRestApplication : Quote[type=success, value=Value[id=12, quote=@springboot with @springframework is pure productivity! Who said in #java one has to write double the code than in other langs? #newFavLib]]
프로그램을 실행하면 로그를 통해 restTemplate으로 받은 random quote가 출력된다.