10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

いよいよRestTemplateがDeprecatedとなるそうなのでRestClientを見ていく

10
Last updated at Posted at 2025-12-22

はじめに

Spring Framework7.0が2025年11月13日、リリースされました。
Java25への対応などの更新があり、リリースの内容を眺めていたのですが、気になったのがこちら。

RestTemplate was previously declared as "feature complete". As of Spring Framework 7.0, we have deprecated this type in our reference documentation, and we will mark it as officially @Deprecated in Spring Framework 7.1. See "the state of HTTP clients" blog post for more details.

引用:https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-7.0-Release-Notes

RestTemplateが7.1にて正式にDeprecatedとなるとのこと。 ここでは廃止の詳細なタイミングについては触れていませんが、8.0で廃止となる計画が示されています。

本稿では、RestTemplateと、後継とされるRestClient、その移行方法など見ていきます。

本稿の内容は、Spring Framework 7.0の時点での内容です。
ソースコードはJava 17の環境で実行しています。

RestTemplateについて

RestTemplateは、2009年12月16日にリリースされたSpring3.0にて追加されました。Spring3.0はSpringMVCでRest通信のサポートを追加したバージョンであり、RestTemplateはRestfulな通信を容易に可能とするテンプレートとして広く使われ、15年以上経つわけですね。

2017年9月28日にリリースされたSpring5.0では、Spring WebFluxモジュールの追加とともに、WebClientが追加されました。この時、併せてRestTemplateはメンテナンスモードへの移行が宣言されたようです。当時のドキュメントは見つけられませんでしたが、当時のJavaDocに以下の通り示されています。

NOTE: As of 5.0 this class is in maintenance mode, with only minor requests for changes and bugs to be accepted going forward. Please, consider using the org.springframework.web.reactive.client.WebClient which has a more modern API and supports sync, async, and streaming scenarios.

引用:https://docs.spring.io/spring-framework/docs/5.3.39/javadoc-api/org/springframework/web/client/RestTemplate.html

WebClientへの移行を促しているようですね。Spring Framework5で開発したプロジェクトでは、非同期通信、ストリーミング通信の要否に関わらず、HTTPクライアントとしてWebClientを選択したプロジェクトも多かったのではないかと思います。

ちなみに、非同期通信をサポートするRestTemplateとして、AsyncRestTemplateなるクラスがSpring4.0でリリースされたのですが、Spring5.0でDeprecated化し、Spring6.0で廃止されています。非同期通信に関してはSpring5.0の時点で完全にWebClientに舵を切ったことがわかりますね。

なぜ廃止されるのか

ここは以下ブログで次のように説明されています。
参考:https://spring.io/blog/2025/09/30/the-state-of-http-clients-in-spring

  • テンプレート形式のAPIをHTTPクライアントに適応すると、メソッドのオーバーライドが必要になる場合が多く、結果として、機能の拡張/開発者体験(IDEのオートコンプリートなど)を阻害する
  • 非同期通信や、ストリーミング通信などの新たな通信方式や、APIバージョニングなどの増えていく需要に対して、テンプレート形式のAPIでは対応が難しかった

一方、WebClientからは可読性、拡張性に優れるfluent APIと呼ばれる形式のAPIを採用しています。後述するRestClientの他に、JdbcClientJmsClientといったfluent APIを採用しているクライアントが続けて追加されていることから、少なくともクライアントという位置づけにおいては、fluent APIで実装するのが適切と、Springコミュニティが考えていると伺えますね。

fluent APIの利点は主に以下のようです。

  • メソッドチェーン形式でAPIを、論理的な順序で記述する為、可読性が高いこと
  • チェーン内で、複数のIFを介してAPIを構成する為、補完時に並ぶメソッドの妥当性やその数の少なさ
  • 機能追加時に引数を追加するメソッドオーバーライドで表現する必要がないため拡張性に優れること

参考①:https://martinfowler.com/bliki/FluentInterface.html
参考②:https://poutsma-principles.com/blog/2025/06/03/fluent-apis-overview/

また、同期通信を担当するHTTPクライアントとして、RestClientが登場し後継としての機能を提供し始めました。Spring 7.0で一通りの機能が整ったと判断された為、改めてRestTemplateDeprecatedとする判断がされたものと推測できます。

RestClientについて

RestClientは、Spring 6.1で追加されました。以下のように説明されています。

  1. 同期通信を扱うHTTPクライアント
  2. WebClientと同様のAPIを持つ
  3. RestTemplateとインフラストラクチャを共有する

参考:https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.1-Release-Notes

Spring 7.0時点で、RestTemplateのJavaDocには以下の通り記載されています。

NOTE: As of 6.1, RestClient offers a more modern API for synchronous HTTP access. For asynchronous and streaming scenarios, consider the reactive WebClient.
RestTemplate and RestClient share the same infrastructure (i.e. request factories, request interceptors and initializers, message converters, etc.), so any improvements made therein are shared as well. However, RestClient is the focus for new higher-level features.

引用:https://docs.spring.io/spring-framework/docs/7.0.0/javadoc-api/org/springframework/web/client/RestTemplate.html

要約すると、6.1以降、モダンなAPIを持っていてRestTemplateと、リクエストファクトリやインターセプタなどのインフラを共有できるRestClientがあるので、今後はこちらを開発していきます。とされています。現時点で、同期通信としてのHTTPクライアントは、RestClientを使うよう推奨するよう変化した。といっていいでしょう。

WebClientで充分ではないのか

WebClientfluent APIを備え、blockメソッドの呼び出しによって、同期通信にも対応が可能です。なおかつRestClientよりも先に追加されています。限られた用途にのみしか使えないRestClientがわざわざ開発され、推奨されているのは何故でしょうか。

WebClientは、非同期通信、ストリーミング通信をサポートする為、同期通信をするだけであれば、必要以上に複雑な構造となっているため。ということのようです。WebClientは別スレッドでの通信など利用上注意が必要です(1敗)。

同期通信を行う。という観点では、RestTemplateは充分な構造を持っていたので、fluent APIを導入するRestClientを開発することにした。ということですね。

また、仮想スレッドの導入によって、同期通信であっても、性能が期待できるという背景もあったようです。仮想スレッドの同期通信の評価については、よければ昨年のAdvent Calendarの記事「仮想スレッド(Virtual Threads)で同期通信は非同期通信を超えるのか?」をご確認ください(※ 端折ってWebClientで同期通信しています)。簡単な検証でしたが、ある程度期待できる結果になっていたかと思います。

参考:https://github.com/spring-projects/spring-framework/issues/29552

RestTemplateからの移行

ここまでの内容で、同期通信を行うHTTPクライアントとしてRestClientが推奨されていることを書きました。ここでは、RestTemplateからRestClientへの移行について見ていきます。なお、この手順については、公式のマニュアルに記載があります。細部はそちらを確認しましょう。
参考:https://spring.pleiades.io/spring-framework/reference/integration/rest-clients.html#migrating-to-restclient

1. RestClientのインスタンスを作る

ログ出力用のInterceptorを追加したRestTemplateを移行することを考えます。

まず、簡単な移行手段としてRestTemplateのインスタンスからRestClientのインスタンスが作成可能です。

- RestTemplate restTemplate = new RestTemplateBuilder()
-         .interceptors(loggingInterceptor)
-         .build();
        
jcRestClient restClient = RestClient.create(restTemplate);

これができるということは、RestTemplateに設定されるクラスの振る舞いや、設定値はRestClientでも設定可能ということですね。まず移行をお試しするならこれで進められそうです。とはいえ、これではRestTemplateの利用が残っていますから、最終的には、RestClient.Builderを使って対応するインスタンスを作成する必要があります。

- RestTemplate restTemplate = new RestTemplateBuilder()
-         .interceptors(loggingInterceptor)
-         .build();
        
+ RestClient restClient = RestClient.builder()
+         .requestInterceptor(loggingInterceptor)
+         .build();

記載の通りで、Interceptorが流用できています。他にもClientRequestFactoryResponseErrorHandlerMessageConverterなどの流用が可能です。

上記のようにインスタンスの移行ができれば、次は通信部分の移行を行っていきます。

2. クライアント通信

通信を実施するRestTemplateのメソッドは、RestClientでのメソッドチェーンでそれぞれ表現が可能です。対応表については、マニュアルを参照してください。

String url = BASE_URL + "/users/" + id;
- User user1 = restTemplate.getForObject(url, User.class);

+ User user2 = restClient.get()
+         .uri(url, id)
+         .retrieve()
+         .body(User.class);

RestTemplateCallbackや、ResponseExtractorは割と使われるかと思いますが、これらはそれぞれ、RestClient側のhttpRequest()や、exchange()で対応する実装を作る必要がありそうですね。

String url = BASE_URL + "/users/" + id;
- ResponseExtractor<User> responseExtractor = response -> {
-     System.out.println("Status Code: " + response.getStatusCode());
-     return new ObjectMapper().readValue(response.getBody(), User.class);
- };
- User user = restTemplate.execute(url, HttpMethod.GET, null, responseExtractor);

+ User user = restClient.get()
+         .uri(BASE_URL + "/users/{id}", id)
+         .exchange((request, response) -> {
+             System.out.println("Status Code: " + response.getStatusCode());
+             return new ObjectMapper().readValue(response.getBody(), User.class);
+         });

RestClient固有の機能を見る

RestClientはモダンなAPIとのことですし、同期通信向けの新機能はRestClientに実装する方針となっていますから、RestTemplateにはない使い方や機能が存在します。いくつか見ていきましょう。

エラーハンドリング

RestTemplateで設定できたResponseErrorHandlerを設定できることは前述した通りですが、これはインスタンスに対してセットするものであり、RestClientでは、デフォルトの振る舞いを規定するものとなります。通信別のエラーハンドリングをする場合、onStatus()を使います。この時、指定したステータスコードにおいては、ResponseErrorHandlerに上書きして振る舞いを設定可能です。

User user = restClient.get()
        .uri(BASE_URL + "/users/{id}", id)
        .retrieve()
        .onStatus(HttpStatusCode::is4xxClientError, (request, response) -> {
            throw new RuntimeException("4xxエラー: " + response.getStatusCode());
        })
        .body(User.class);

APIバージョニング

RestTemplateでは、拡張性が課題となり追加を見送られた機能だったようですが、Spring7.0にて、RestClientにAPIバージョニングをサポートする機能が追加されました。

RestClient restClient = RestClient.builder()
        .requestInterceptor(loggingInterceptor)
        .apiVersionInserter(ApiVersionInserter.useHeader("API-Version"))
        .defaultApiVersion(1.0)
        .build();

User user = restClient.get()
        .uri(url, id)
        .apiVersion(2.0)
        .retrieve()
        .body(User.class);

ヘッダにて呼び出すAPIのバージョンを指定するよう設定しており、2.0のバージョンのAPI(デフォルトは1.0に設定)を呼び出しています。また、サーバ側にもAPIバージョニングのサポートが追加されています。

まとめ

本稿ではRestTemplateと後継となるRestClientについて、経緯やその移行について述べました。筆者は入社してからこの方、Spring5.xにふれる機会が多かったので、もろもろ興味深い内容でした。

WebClientは同期通信だけを行う場合には複雑な機能となっており、RestTemplateDeprecatedおよび廃止が計画されています。今後はRestClient利用やRestTemplateからの移行が増えることと思われます。RestClientの今後の活躍に期待大ですね。

振り返ると、Springの各メジャーバージョンでHTTPクライアント周りの追加や、Deprecatedが行われていることになります。今後も注目していきたいなと思った次第です。ここまでお付き合いいただきありがとうございました。

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?