RestTemplate で REST API の利用

このガイドでは、RESTful Web サービスを使用するアプリケーションを作成するプロセスを順を追って説明します。

構築するもの

Spring の RestTemplate を使用して、http://localhost:8080/api/random でランダムな Spring Boot の引用を取得するアプリケーションを作成します。

必要なもの

本ガイドの完成までの流れ

ほとんどの Spring 入門ガイドと同様に、最初から始めて各ステップを完了するか、すでに慣れている場合は基本的なセットアップステップをバイパスできます。いずれにしても、最終的に動作するコードになります。

最初から始めるには、Spring Initializr から開始に進みます。

基本スキップするには、次の手順を実行します。

完了したときは、gs-consuming-rest/complete のコードに対して結果を確認できます。

Spring Initializr から開始

IDE を使用する場合はプロジェクト作成ウィザードを使用します。IDE を使用せずにコマンドラインなどで開発する場合は、この事前に初期化されたプロジェクトからプロジェクトを ZIP ファイルとしてダウンロードできます。このプロジェクトは、このチュートリアルの例に合うように構成されています。

プロジェクトを手動で初期化するには:

  1. IDE のメニューまたはブラウザーから Spring Initializr を開きます。アプリケーションに必要なすべての依存関係を取り込み、ほとんどのセットアップを行います。

  2. Gradle または Maven のいずれかと、使用する言語を選択します。このガイドは、Java を選択したことを前提としています。

  3. 依存関係をクリックして、Spring Web を選択します。

  4. 生成をクリックします。

  5. 結果の ZIP ファイルをダウンロードします。これは、選択して構成された Web アプリケーションのアーカイブです。

EclipseIntelliJ のような IDE は新規プロジェクト作成ウィザードから Spring Initializr の機能が使用できるため、手動での ZIP ファイルのダウンロードやインポートは不要です。
プロジェクトを Github からフォークして、IDE または他のエディターで開くこともできます。

REST リソースの取得

プロジェクトのセットアップが完了すると、RESTful サービスを使用する単純なアプリケーションを作成できます。

その前に、REST リソースのソースが必要です。そのようなサービスの例を 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 (2 番目の見積もり用) などがあります (現時点では最大 10 個)。

Web ブラウザーまたは curl を介してその URL をリクエストすると、次のような JSON ドキュメントを受け取ります。

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

これは十分に簡単ですが、ブラウザーや curl を介して取得する場合は、それほど便利ではありません。

REST Web サービスを利用するより便利なメソッドは、プログラムを使用することです。そのタスクを支援するために、Spring は RestTemplate (Javadoc) と呼ばれる便利なテンプレートクラスを提供します。RestTemplate は、ほとんどの RESTful サービスとの対話を 1 行の呪文にします。また、そのデータをカスタムドメイン型にバインドすることもできます。

まず、必要なデータを含むドメインクラスを作成する必要があります。次のリストは、ドメインクラスとして使用できる Quote レコードクラスを示しています。

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

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record Quote(String type, Value value) { }

この単純な Java レコードクラスには、Jackson JSON 処理ライブラリの @JsonIgnoreProperties でアノテーションが付けられ、この型にバインドされていないプロパティを無視する必要があることを示します。

データをカスタム型に直接バインドするには、API から返された JSON ドキュメントのキーとまったく同じになるように変数名を指定する必要があります。JSON ドキュメントの変数名とキーが一致しない場合、@JsonProperty アノテーションを使用して JSON ドキュメントの正確なキーを指定できます。(この例では、各変数名を JSON キーに一致させるため、ここでそのアノテーションは必要ありません。)

内部引用自体を埋め込むために、追加のクラスも必要です。Value レコードクラスはその必要性を満たし、次のリスト ( src/main/java/com/example/consumingrest/Value.java) に示されています。

package com.example.consumingrest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public record Value(Long id, String quote) { }

これは同じアノテーションを使用しますが、他のデータフィールドにマップします。

アプリケーションの終了

Initializr は、main() メソッドを使用してクラスを作成します。次のリストは、Initializr が ( src/main/java/com/example/consumingrest/ConsumingRestApplication.java で) 作成するクラスを示しています。

package com.example.consumingrest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumingRestApplication {

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

}

次に、他のいくつかを ConsumingRestApplication クラスに追加して、RESTful ソースからの引用を表示する必要があります。以下を追加する必要があります。

  • ログ(この例ではコンソール)に出力を送信するロガー。

  • Jackson JSON 処理ライブラリを使用して受信データを処理する RestTemplate

  • 起動時に RestTemplate を実行する(その結果、見積を取得する) CommandLineRunner

次のリストは、完成した ConsumingRestApplication クラス(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.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());
		};
	}
}

最後に、サーバーのポートを設定する必要があります。quoters アプリケーションはデフォルトのサーバーポート 8080 を使用するため、このアプリケーションも同じポートを使用できません。次の行をアプリケーションプロパティ (Initializr が作成したもの) に追加することで、サーバーポートを 8081 に設定できます。

server.port=8081

アプリケーションの実行

コマンドラインから Gradle または Maven を使用してアプリケーションを実行できます。必要なすべての依存関係、クラス、リソースを含む単一の実行可能 JAR ファイルを構築して実行することもできます。実行可能な jar を構築すると、開発ライフサイクル全体、さまざまな環境などで、アプリケーションとしてサービスを簡単に提供、バージョン管理、デプロイできます。

Gradle を使用する場合、./gradlew bootRun を使用してアプリケーションを実行できます。または、次のように、./gradlew build を使用して JAR ファイルをビルドしてから、JAR ファイルを実行できます。

java -jar build/libs/gs-consuming-rest-0.1.0.jar

Maven を使用する場合、./mvnw spring-boot:run を使用してアプリケーションを実行できます。または、次のように、./mvnw clean package で JAR ファイルをビルドしてから、JAR ファイルを実行できます。

java -jar target/gs-consuming-rest-0.1.0.jar
ここで説明する手順は、実行可能な JAR を作成します。クラシック WAR ファイルを作成することもできます。

次のような出力が表示されますが、ランダムな引用が表示されます。

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.'}}
Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.consumingrest.Quote] というエラーが表示された場合は、バックエンドサービスに接続できない環境にいる可能性があります (接続できれば JSON が送信されます)。もしかしたら、企業のプロキシの後ろにいるかもしれません。http.proxyHost と http.proxyPort のシステムプロパティを環境に適した値に設定してみてください。

要約

おめでとう! Spring Boot を使用して、簡単な REST クライアントを開発しました。

コードを入手する