Guide_Consuming a RESTful Web Service

Dev.Hammy·2023년 12월 9일
0

Spring Guides

목록 보기
3/46

RESTful 웹 서비스를 consume 하는 application을 생성해보겠습니다.

What You Will Build

RestTemplate을 사용하여 Spring Boot 랜덤 quatation을 http://localhost:8080/api/random 으로 반환하는 애플리케이션을 build 해보겠습니다.

Starting with Spring Initializr

스프링 이니셜라이저를 이용하여 Spring Web을 의존성으로 추가하고 자바 17, Gradle-Groovy, Jar 설정으로 생성했다.

Fetching a REST Resource

프로젝트 설정이 완료되면 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) { }

Finishing the Application

이니셜라이저가 자동으로 생성한 main() 메서드가 있는 클래스(src/main/java/com/example/consumingrest/ConsumingRestApplication.java)에 아래 요소들을 추가하여 RESTful 소스 인용문을 표시할 수 있도록 합니다.

  • 출력을 로그(이 예에서는 콘솔)로 보내기 위한 로거.
  • Jackson JSON 처리 라이브러리를 사용하여 들어오는(incoming) 데이터를 처리하는 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());
        };
    }
}
  1. LoggerFactory: 로깅에 사용되는 SLF4J(Logger Facade for Java)의 Logger를 가져오는 팩토리 메서드입니다.
  • 일반적으로 팩토리 메서드나 팩토리 패턴을 사용하여 객체를 생성하면, 팩토리에 따라 객체의 생성 여부나 방법이 결정됩니다. 이 때, 팩토리에 의해 생성된 객체는 팩토리 구현에 따라 여러 번 호출되더라도 동일한 인스턴스를 반환할 수 있습니다.
  • final로 선언된 로거는 한 번 생성되고 할당된 이후에는 변경되지 않으므로 일관성 있는 로깅 방식을 유지할 수 있습니다
  1. RestTemplate: Spring에서 제공하는 HTTP 통신을 위한 클라이언트 라이브러리로, HTTP 요청을 보내고 응답을 받을 수 있게 해줍니다.

  2. RestTemplateBuilder: RestTemplate을 생성하기 위한 빌더 클래스로, 다양한 구성 옵션을 제공하며 RestTemplate의 인스턴스를 생성합니다.

  • 빌더 패턴은 객체 생성 과정을 단순화하고, 유연하게 생성자 인자를 다루며, 객체의 속성을 설정하기 위한 패턴입니다.
  • 일반적으로 빌더 패턴을 사용하여 단일 인스턴스를 생성하게 되면, 그 인스턴스는 일반적으로 싱글턴과 유사한 형태를 가질 수 있습니다. 하지만 빌더 패턴 자체가 싱글턴을 만들기 위한 목적은 아닙니다.
  1. @Bean: Spring 애플리케이션 컨텍스트에 빈(Bean)을 추가하기 위한 어노테이션으로, 해당 메서드가 반환하는 객체를 빈으로 등록합니다.

  2. @Profile: Spring에서 활성화될 프로파일을 지정하는 어노테이션으로, 특정 프로파일에만 적용되는 설정을 지정할 수 있습니다.

  • 특정한 환경 또는 프로파일에 따라 다른 빈을 로드하고 싶을 때 사용됩니다.

  • 예를 들어, 개발용과 프로덕션용 설정을 분리하고 싶을 때 @Profile을 사용하여 각각의 프로파일에 맞는 빈을 로드합니다.

  • @Import

    • 어노테이션은 다른 설정 클래스나 구성을 현재 설정 클래스로 가져오도록 지정합니다.
    • 이를 통해 여러 설정을 조합하거나, 설정을 분리하여 재사용할 수 있습니다.
    • 주로 여러 개의 구성 클래스를 한 곳에서 묶어서 사용하고 싶을 때 활용됩니다.
  • @Scope

    • 빈의 범위(scope)를 지정하는데 사용됩니다. 기본적으로 스프링에서는 싱글톤(scope="singleton")이 기본값입니다. 따라서 스프링 애플리케이션 컨텍스트에서 해당 빈은 기본적으로 싱글톤으로 동작합니다.
    • @Scope 어노테이션을 사용하여 프로토타입(scope="prototype")이나 다른 커스텀 범위로 빈을 정의할 수 있습니다.
    • @Profile은 어노테이션을 붙이는 빈에 제한이 없지만, @Scope는 빈의 범위를 설정하는 데 사용되므로 일부 빈에만 적용됩니다.
  1. CommandLineRunner: Spring Boot 애플리케이션을 시작할 때 실행되는 인터페이스입니다. run 메서드를 구현하여 애플리케이션 실행 시 원하는 동작을 정의할 수 있습니다.
  • CommandLineRunnerrun 메서드의 args: Java 애플리케이션을 실행할 때 전달되는 커맨드 라인 인수들을 나타내는 문자열 배열입니다.

  • main 메서드의 args: Java 애플리케이션의 진입점으로, 커맨드 라인에서 전달되는 인수들을 나타내는 문자열 배열입니다. SpringApplication.run 메서드에 전달되는 인수로 사용됩니다.

마지막으로 서버 포트를 설정해야 합니다. quoters 애플리케이션은 기본 서버 포트인 8080을 사용하므로 이 애플리케이션도 동일한 포트를 사용할 수 없습니다. application.properties(Initializr가 생성한)에 다음 줄을 추가하여 서버 포트를 8081로 설정할 수 있습니다.

server.port=8081

Running the Application

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가 출력된다.

0개의 댓글