The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
このページを編集

REST クライアントの利用

このガイドでは、REST APIと対話するための REST クライアントの使用方法について説明します。REST クライアントは、Quarkus REST(旧RESTEasy Reactive)と互換性のある REST クライアントの実装です。

アプリケーションでクライアントを使用し、REST エンドポイントを公開する場合は、サーバー部分に Quarkus REST を使用してください。

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.15

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

ソリューション

次のセクションの指示に従ってアプリケーションを段階的に作成することをお勧めします。ただし、完成した例に直接進むことも可能です。

Git リポジトリーをクローンします: git clone https://github.com/quarkusio/quarkus-quickstarts.git、または アーカイブ をダウンロードします。

ソリューションは rest-client-quickstart ディレクトリー にあります。

Maven プロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新しいプロジェクトを作成します。

コマンドラインインタフェース
quarkus create app org.acme:rest-client-quickstart \
    --extension='rest-jackson,rest-client-jackson' \
    --no-code
cd rest-client-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストールと使用方法の詳細については、 Quarkus CLI ガイドを参照してください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.35.2:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=rest-client-quickstart \
    -Dextensions='rest-jackson,rest-client-jackson' \
    -DnoCode
cd rest-client-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

Windowsユーザーの場合:

  • cmdを使用する場合、(バックスラッシュ \ を使用せず、すべてを同じ行に書かないでください)。

  • Powershellを使用する場合は、 -D パラメータを二重引用符で囲んでください。例: "-DprojectArtifactId=rest-client-quickstart"

このコマンドは、REST エンドポイントを持つ Maven プロジェクトを生成し、以下をインポートします。

  • REST サーバーのサポートには rest-jackson エクステンションを使用します。Jackson を使用したくない場合は、代わりに rest を使用してください。

  • REST クライアントのサポートには rest-client-jackson エクステンションを使用します。Jackson を使用したくない場合は、代わりに rest-client を使用してください。

Quarkus プロジェクトがすでに設定されている場合は、プロジェクトのベースディレクトリーで次のコマンドを実行することで、rest-client-jackson エクステンションをプロジェクトに追加できます。

コマンドラインインタフェース
quarkus extension add rest-client-jackson
Maven
./mvnw quarkus:add-extension -Dextensions='rest-client-jackson'
Gradle
./gradlew addExtension --extensions='rest-client-jackson'

これにより、ビルドファイルに以下が追加されます。

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-rest-client-jackson</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-rest-client-jackson")

モデルのセットアップ

このガイドでは、stage.code.quarkus.io サービスが提供する REST API の一部を利用する方法をデモします。まず最初に、使用するモデルを Extension POJO の形式でセットアップします。

src/main/java/org/acme/rest/client/Extension.java ファイルを作成し、以下の内容を設定します。

package org.acme.rest.client;

import java.util.List;

public class Extension {

    public String id;
    public String name;
    public String shortName;
    public List<String> keywords;

}

上記のモデルは、サービスによって提供されるフィールドのサブセットに過ぎませんが、このガイドの目的には十分です。

インターフェースの作成

REST クライアントの使用は、適切な Jakarta REST および MicroProfile アノテーションを使用してインターフェースを作成するのと同じくらい簡単です。今回の場合、インターフェースは src/main/java/org/acme/rest/client/ExtensionsService.java で作成し、以下の内容を持つ必要があります。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.Set;

@Path("/extensions")
@RegisterRestClient
public interface ExtensionsService {

    @GET
    Set<Extension> getById(@QueryParam("id") String id);
}

getById メソッドは、私たちのコードに、Code Quarkus API から ID を指定してエクステンションを問い合わせる機能を与えます。クライアントがすべてのネットワーキングとマーシャリングを処理してくれるので、このような技術的な詳細は一切ありません。

上記のコードにあるアノテーションの目的は次のとおりです。

  • @RegisterRestClient により、Quarkus は、このインターフェースが REST クライアントとして CDI インジェクションに利用可能であることを知ることができます。

  • @Path@GET@QueryParam は、サービスへのアクセス方法を定義するために使用される標準の Jakarta REST アノテーションです。

quarkus-rest-client-jackson エクステンションがインストールされている場合、メディアタイプが @Produces または @Consumes アノテーションによって明示的に設定されていない限り、Quarkus はほとんどの戻り値に対してデフォルトで application/json メディアタイプを使用します。

JSON のデフォルトに依存しない場合は、エンドポイントに @Produces および @Consumes アノテーションを付けて、期待されるコンテンツタイプを正確に定義することを強く推奨します。これにより、ネイティブ実行可能ファイルに含まれる Jakarta REST プロバイダー(コンバーターと見なすことができます)の数を減らすことができます。

上記の getById メソッドはブロッキング呼び出しです。イベントループで呼び出さないでください。非同期サポート セクションでは、ノンブロッキング呼び出しを行う方法について説明しています。

クエリーパラメーター

クエリーパラメーターを指定する最も簡単な方法は、クライアントメソッドのパラメーターに @QueryParam または @RestQuery のアノテーションを付けることです。@RestQuery@QueryParam と同等ですが、名前を省略することができます。さらに、クエリーパラメーターを Map として渡すこともでき、事前にパラメーターがわからない場合に便利です。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.reactive.RestQuery;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MultivaluedMap;
import java.util.Map;
import java.util.Set;
import java.util.Optional;

@Path("/extensions")
@RegisterRestClient(configKey = "extensions-api")
public interface ExtensionsService {

    @GET
    Set<Extension> getById(@QueryParam("id") String id);

    @GET
    Set<Extension> getByName(@RestQuery String name); (1)

    @GET
    Set<Extension> getByOptionalName(@RestQuery Optional<String> name);

    @GET
    Set<Extension> getByFilter(@RestQuery Map<String, String> filter); (2)

    @GET
    Set<Extension> getByFilters(@RestQuery MultivaluedMap<String, String> filters); (3)

}
1 @RestQuery はキー name を持つパラメーターを含みます
2 Map エントリは、ちょうど 1 つのクエリーパラメーターを表します
3 MultivaluedMap を使用すると、配列値を送信できます

@ClientQueryParam の使用

リクエストにクエリーパラメーターを追加するもうひとつの方法は、REST クライアントインターフェースあるいはそのインターフェースの特定のメソッドに @io.quarkus.rest.client.reactive.ClientQueryParam を使用することです。アノテーションではクエリーパラメーター名を指定し、値は定数や設定プロパティー、あるいはメソッドの起動時に決定できます。

以下の例は、さまざまな使用方法を示しています。

@ClientQueryParam(name = "my-param", value = "${my.property-value}") (1)
public interface Client {
    @GET
    String getWithParam();

    @GET
    @ClientQueryParam(name = "some-other-param", value = "other") (2)
    String getWithOtherParam();

    @GET
    @ClientQueryParam(name = "param-from-method", value = "{with-param}") (3)
    String getFromMethod();

    default String withParam(String name) {
        if ("param-from-method".equals(name)) {
            return "test";
        }
        throw new IllegalArgumentException();
    }
}
1 インターフェースに @ClientQueryParam を配置することで、my-param がクライアントのすべてのリクエストに追加されるようにします。${…​} 構文を使用したため、パラメーターの実際の値は my.property-value 設定プロパティーを使用して取得されます。
2 getWithOtherParam が呼び出されると、my-param クエリーパラメーターに加えて、値が othersome-other-param も追加されます。
3 getFromMethod が呼び出されると、my-param クエリーパラメーターに加えて、値が testparam-from-method も追加されます(これは、withParam メソッドが param-from-method で呼び出されたときに返す値であるため)。

インターフェースメソッドに @QueryParam でアノテーションが付けられた引数がある場合、その引数は @ClientQueryParam アノテーションで指定されたものよりも優先されることに注意してください。

このアノテーションの詳細は、@ClientQueryParam の Javadoc で確認できます。

フォームパラメーター

フォームパラメーターは、@RestForm(または @FormParam)アノテーションを使用して指定できます。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.reactive.RestForm;

import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.core.MultivaluedMap;
import java.util.Map;
import java.util.Set;

@Path("/extensions")
@RegisterRestClient(configKey = "extensions-api")
public interface ExtensionsService {

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    Set<Extension> postId(@FormParam("id") String id);

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    Set<Extension> postName(@RestForm String name);

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    Set<Extension> postFilter(@RestForm Map<String, String> filter);

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    Set<Extension> postFilters(@RestForm MultivaluedMap<String, String> filters);

}

@ClientFormParam の使用

フォームパラメーターは、@ClientQueryParam と同様に @ClientFormParam を使用して指定することもできます。

@ClientFormParam(name = "my-param", value = "${my.property-value}")
public interface Client {
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    String postWithParam();

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @ClientFormParam(name = "some-other-param", value = "other")
    String postWithOtherParam();

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @ClientFormParam(name = "param-from-method", value = "{with-param}")
    String postFromMethod();

    default String withParam(String name) {
        if ("param-from-method".equals(name)) {
            return "test";
        }
        throw new IllegalArgumentException();
    }
}

このアノテーションの詳細は、@ClientFormParam の Javadoc で確認できます。

パスパラメーター

GET リクエストにパスパラメーターが必要な場合は、@QueryParam の代わりに (または加えて) @PathParam("parameter-name") アノテーションを使用できます。パスパラメーターとクエリーパラメーターは、必要に応じて以下の例のように組み合わせることができます。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
import java.util.Set;

@Path("/extensions")
@RegisterRestClient
public interface ExtensionsService {

    @GET
    @Path("/stream/{stream}")
    Set<Extension> getByStream(@PathParam("stream") String stream, @QueryParam("id") String id);
}

動的ベース URL

REST クライアントでは、 io.quarkus.rest.client.reactive.Url アノテーションを使用して、呼び出しごとにベース URL をオーバーライドできます。

簡単な例を次に示します。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
import java.util.Set;

import io.quarkus.rest.client.reactive.Url;

@Path("/extensions")
@RegisterRestClient
public interface ExtensionsService {

    @GET
    @Path("/stream/{stream}")
    Set<Extension> getByStream(@Url String url, @PathParam("stream") String stream, @QueryParam("id") String id);
}

url パラメーターが null 以外の場合、クライアントに設定されているベース URL がオーバーライドされます (デフォルトのベース URL 設定は引き続き必須です)。

大規模ペイロードの送信

REST Client は、以下のいずれかの型を使用する場合、メモリー内にコンテンツをバッファーリングすることなく、任意の大きさの HTTP 本文を送信できます。

  • InputStream

  • Multi<io.vertx.mutiny.core.buffer.Buffer>

さらに、以下のいずれかの型を使用すると、クライアントは任意の大きさのファイルを送信することもできます。

  • File

  • Path

その他のレスポンスプロパティーの取得

RestResponse の使用

HTTP レスポンスのボディだけでなく、ステータスコードやヘッダーなどの他のプロパティーも取得する必要がある場合は、メソッドから org.jboss.resteasy.reactive.RestResponse を返すことができます。この例は次のようになります。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.jboss.resteasy.reactive.RestQuery;
import org.jboss.resteasy.reactive.RestResponse;

import java.util.Set;

@Path("/extensions")
@RegisterRestClient
public interface ExtensionsService {

    @GET
    RestResponse<Set<Extension>> getByIdResponseProperties(@RestQuery String id);
}
REST クライアントを RestResponse を戻り値の型として使用するように設定する場合、レスポンスのステータスコードが成功範囲 (2xx) にない場合に WebApplicationException がスローされないように、Quarkus REST クライアントのデフォルト例外マッパー を無効にする必要があります。
また、Jakarta REST 型 Response を使用することもできますが、エンティティーに対して強い型付けはされていません。

Jakarta REST リソースの作成

src/main/java/org/acme/rest/client/ExtensionsResource.java ファイルを以下の内容で作成してください。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import java.util.Set;

@Path("/extension")
public class ExtensionsResource {

    @RestClient (1)
    ExtensionsService extensionsService;


    @GET
    @Path("/id/{id}")
    public Set<Extension> id(String id) {
        return extensionsService.getById(id);
    }

    @GET
    @Path("/properties")
    public RestResponse<Set<Extension>> responseProperties(@RestQuery String id) {
        RestResponse<Set<Extension>> clientResponse = extensionsService.getByIdResponseProperties(id); (2)
        String contentType = clientResponse.getHeaderString("Content-Type");
        int status = clientResponse.getStatus();
        String setCookie = clientResponse.getHeaderString("Set-Cookie");
        Date lastModified = clientResponse.getLastModified();

        Log.infof("content-Type: %s status: %s Last-Modified: %s Set-Cookie: %s", contentType, status, lastModified,
                setCookie);

        return RestResponse.fromResponse(clientResponse);
    }
}

このリストには 2 つの興味深い点があります。

1 クライアントスタブには、通常の CDI @Inject ではなく、 @RestClient アノテーションが注入されます。
2 org.jboss.resteasy.reactive.RestResponse は、RestClient から RestResponse を介してレスポンスプロパティーを直接取得する効果的な方法として使用されます。詳細は RestResponse の使用 を参照してください。

設定の作成

REST 呼び出しが行われるベース URL を決定するために、REST Client は application.properties からの設定を使用します。プロパティーの名前は、以下のコードで示される特定の規則に従う必要があります。

# Your configuration properties
quarkus.rest-client."org.acme.rest.client.ExtensionsService".url=https://stage.code.quarkus.io/api (1)
1 この設定を行うと、org.acme.rest.client.ExtensionsService を使用して実行されるすべてのリクエストは、ベース URL として https://stage.code.quarkus.io/api を使用することを意味します。上記の設定を使用すると、ExtensionsServicegetById メソッドを io.quarkus:quarkus-rest-client という値で呼び出すと、https://stage.code.quarkus.io/api/extensions?id=io.quarkus:quarkus-rest-client に HTTP GET リクエストが行われることになります。

org.acme.rest.client.ExtensionsService は、前のセクションで作成した ExtensionsService インターフェイスの完全修飾名と 一致しなければならない ことに注意してください。

設定を容易にするために、 @RegisterRestClientconfigKey プロパティーを使用して、インターフェイスの完全修飾名とは異なる設定ルートを使用することができます。

@RegisterRestClient(configKey="extensions-api")
public interface ExtensionsService {
    [...]
}
# Your configuration properties
quarkus.rest-client.extensions-api.url=https://stage.code.quarkus.io/api
quarkus.rest-client.extensions-api.scope=jakarta.inject.Singleton

クライアントのベース URL の設定は 必須 ですが、REST Client は @io.quarkus.rest.client.reactive.Url アノテーションを使用して、呼び出しごとにベース URL をオーバーライドすることをサポートしています。

すべての証明書を信頼し、SSL ホスト名検証を無効にする

このプロパティーセットは実稼働環境では使用しないでください。

特定の REST クライアントの TLS 接続を設定して、すべての証明書を信頼し、TLS エクステンションを使用してホスト名の検証を無効にすることができます。まず、TLS 設定バケットを設定する必要があります。

すべての証明書を信頼するには、次のように指定します。

quarkus.tls.tls-disabled.trust-all=true

SSL ホスト名検証を無効にするには、次のように指定します。

quarkus.tls.tls-disabled.hostname-verification-algorithm=NONE

最後に、適切な TLS 設定名を使用して REST クライアントを設定します。

quarkus.rest-client.extensions-api.tls-configuration-name=tls-disabled

HTTP/2 のサポート

REST Client では、HTTP/2 はデフォルトで無効になっています。有効にしたい場合は、次のように設定できます。

// for all REST Clients:
quarkus.rest-client.http2=true
// or for a single REST Client:
quarkus.rest-client.extensions-api.http2=true

あるいは、Application-Layer Protocol Negotiation (ALPN) TLS エクステンションを有効にすると、クライアントはサーバーが互換性のある HTTP バージョンの中からどのバージョンを使用するかをネゴシエートします。デフォルトでは、まず HTTP/2 を使用しようとし、有効になっていない場合は HTTP/1.1 を使用します。有効にしたい場合は、次のように設定できます。

quarkus.rest-client.alpn=true
// or for a single REST Client:
quarkus.rest-client.extensions-api.alpn=true

QuarkusRestClientBuilder を使用したプログラムによるクライアント作成

クライアントに @RegisterRestClient アノテーションを付け、 @RestClient でクライアントを注入する代わりに、プログラムで REST Client を作成することもできます。これは QuarkusRestClientBuilder で行います。

このアプローチでは、クライアントインターフェイスは次のようになります。

package org.acme.rest.client;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.Set;

@Path("/extensions")
public interface ExtensionsService {

    @GET
    Set<Extension> getById(@QueryParam("id") String id);
}

そして、サービスは次のようになります。

package org.acme.rest.client;

import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import java.net.URI;
import java.util.Set;

@Path("/extension")
public class ExtensionsResource {

    private final ExtensionsService extensionsService;

    public ExtensionsResource() {
        extensionsService = QuarkusRestClientBuilder.newBuilder()
            .baseUri(URI.create("https://stage.code.quarkus.io/api"))
            .build(ExtensionsService.class);
    }

    @GET
    @Path("/id/{id}")
    public Set<Extension> id(String id) {
        return extensionsService.getById(id);
    }
}

QuarkusRestClientBuilder インターフェイスは、追加の設定オプションを使用してクライアントをプログラムで作成するための Quarkus 固有の API です。これ以外にも、Microprofile API の RestClientBuilder インターフェイスを使用することもできます。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.RestClientBuilder;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import java.net.URI;
import java.util.Set;

@Path("/extension")
public class ExtensionsResource {

    private final ExtensionsService extensionsService;

    public ExtensionsResource() {
        extensionsService = RestClientBuilder.newBuilder()
            .baseUri(URI.create("https://stage.code.quarkus.io/api"))
            .build(ExtensionsService.class);
    }

    // ...
}

カスタム HTTP オプションの使用

REST Client は、内部的に Vert.x HTTP Client を使用して、ネットワーク接続をします。REST Client エクステンションでは、プロパティーを使っていくつかの設定を行うことができます。以下に例を示します。

  • quarkus.rest-client.client-prefix.connect-timeout で、接続タイムアウトをミリ秒単位で設定します。

  • quarkus.rest-client.client-prefix.max-redirects でリダイレクトの回数を制限できます。

しかし、Vert.x HTTP Client 内には、接続を設定するための多くのオプションがあります。 このリンク の Vert.x HTTP Client Options API ですべてのオプションを参照してください。

REST Client が内部的に使用している Vert.x HTTP Client インスタンスを完全にカスタマイズするには、CDI 経由で、またはプログラムでクライアントを作成するときに、カスタム HTTP Client Options インスタンスを提供できます。

CDI を介して HTTP Client Options を提供する方法の例を見てみましょう。

package org.acme.rest.client;

import jakarta.enterprise.inject.Produces;
import jakarta.ws.rs.ext.ContextResolver;

import io.vertx.core.http.HttpClientOptions;
import io.quarkus.arc.Unremovable;

@Provider
public class CustomHttpClientOptions implements ContextResolver<HttpClientOptions> {

    @Override
    public HttpClientOptions getContext(Class<?> aClass) {
        HttpClientOptions options = new HttpClientOptions();
        // ...
        return options;
    }
}

これで、すべての REST Client がカスタム HTTP Client Options を使用するようになります。

もう一つの方法は、プログラムでクライアントを作成する際に、カスタム HTTP Client オプションを提供することです。

package org.acme.rest.client;

import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import java.net.URI;
import java.util.Set;

import io.vertx.core.http.HttpClientOptions;

@Path("/extension")
public class ExtensionsResource {

    private final ExtensionsService extensionsService;

    public ExtensionsResource() {
        HttpClientOptions options = new HttpClientOptions();
        // ...

        extensionsService = QuarkusRestClientBuilder.newBuilder()
            .baseUri(URI.create("https://stage.code.quarkus.io/api"))
            .httpClientOptions(options) (1)
            .build(ExtensionsService.class);
    }

    // ...
}
1 クライアントはCDI経由で提供されたHTTPクライアントオプションよりも、登録されたHTTPクライアントオプションを使用します。

リダイレクト

HTTPサーバーは、ステータスコードが「3」で始まるレスポンスと、リダイレクト先のURLを保持するHTTPヘッダー「Location」を送信することで、レスポンスを別の場所にリダイレクトできます。REST Client が HTTP サーバーからリダイレクトレスポンスを受信しても、新しい場所への再リクエストを自動的に実行することはありません。「follow-redirects」プロパティーを追加することで、REST Client で自動リダイレクトを有効にできます。

  • quarkus.rest-client.follow-redirects で、すべてのRESTクライアントに対してリダイレクトが有効になります。

  • quarkus.rest-client.<client-prefix>.follow-redirects で、特定のRESTクライアントに対するリダイレクトを有効にすることができます。

このプロパティがtrueの場合、REST Clientは、HTTPサーバーからリダイレクトレスポンスを受信すると、新しいリクエストを実行します。

さらに、プロパティ "max-redirects" を使って、リダイレクトの回数を制限することができます。

重要な注意点として、 RFC2616 仕様によると、デフォルトではリダイレクトは GET または HEAD メソッドに対してのみ実行されます。しかし、REST Client では、 @ClientRedirectHandler アノテーションを使用するか、CDI を利用するか、またはクライアント作成時にプログラム的に設定することで、POST や PUT メソッドのリダイレクトを有効にしたり、より複雑なロジックに従ってリダイレクトを行うカスタムリダイレクトハンドラーを指定できます。

@ClientRedirectHandler アノテーションを使用して独自のカスタムリダイレクトハンドラーを登録する方法の例を見てみましょう。

import jakarta.ws.rs.core.Response;

import io.quarkus.rest.client.reactive.ClientRedirectHandler;

@RegisterRestClient(configKey="extensions-api")
public interface ExtensionsService {
    @ClientRedirectHandler
    static URI alwaysRedirect(Response response) {
        if (Response.Status.Family.familyOf(response.getStatus()) == Response.Status.Family.REDIRECTION) {
            return response.getLocation();
        }

        return null;
    }
}

"alwaysRedirect" リダイレクトハンドラーは、指定された REST Client (この例では "ExtensionsService" クライアント) によってのみ使用されます。

または、CDI 経由ですべての REST Client にカスタムリダイレクトハンドラーを提供することもできます。

import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;

import org.jboss.resteasy.reactive.client.handlers.RedirectHandler;

@Provider
public class AlwaysRedirectHandler implements ContextResolver<RedirectHandler> {

    @Override
    public RedirectHandler getContext(Class<?> aClass) {
        return response -> {
            if (Response.Status.Family.familyOf(response.getStatus()) == Response.Status.Family.REDIRECTION) {
                return response.getLocation();
            }
            // no redirect
            return null;
        };
    }
}

これで、すべての REST Client が、お客様のカスタムリダイレクトハンドラーを使用するようになります。

別の方法として、クライアントを作成するときにプログラムで提供する方法があります。

@Path("/extension")
public class ExtensionsResource {

    private final ExtensionsService extensionsService;

    public ExtensionsResource() {
        extensionsService = QuarkusRestClientBuilder.newBuilder()
            .baseUri(URI.create("https://stage.code.quarkus.io/api"))
            .register(AlwaysRedirectHandler.class) (1)
            .build(ExtensionsService.class);
    }

    // ...
}
1 クライアントは、CDI 経由で提供されたリダイレクトハンドラーよりも、登録されたリダイレクトハンドラーを使用します (存在する場合)。

テストの更新

次に、エンドポイントに加えられた変更を反映させるために、機能テストを更新する必要があります。 src/test/java/org/acme/rest/client/ExtensionsResourceTest.java ファイルを編集し、テストの内容を以下のように変更します。

package org.acme.rest.client;

import io.quarkus.test.junit.QuarkusTest;

import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.greaterThan;

@QuarkusTest
public class ExtensionsResourceTest {

    @Test
    public void testExtensionsIdEndpoint() {
        given()
            .when().get("/extension/id/io.quarkus:quarkus-rest-client")
            .then()
            .statusCode(200)
            .body("$.size()", is(1),
                "[0].id", is("io.quarkus:quarkus-rest-client"),
                "[0].name", is("REST Client"),
                "[0].keywords.size()", greaterThan(1),
                "[0].keywords", hasItem("rest-client"));
    }
}

上のコードでは、 REST Assuredjson-path 機能を使用しています。

非同期サポート

クライアントのリアクティブな性質を最大限に活用するには、REST Client エクステンションのノンブロッキングフレーバーを使用します。このエクステンションは CompletionStageUni をサポートしています。それでは、実際に ExtensionsService REST インターフェイスに getByIdAsync メソッドを追加して、この動きを見てみましょう。コードは以下のようになります。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.Set;
import java.util.concurrent.CompletionStage;

@Path("/extensions")
@RegisterRestClient(configKey = "extensions-api")
public interface ExtensionsService {

    @GET
    Set<Extension> getById(@QueryParam("id") String id);

    @GET
    CompletionStage<Set<Extension>> getByIdAsync(@QueryParam("id") String id);
}

src/main/java/org/acme/rest/client/ExtensionsResource.java ファイルを開き、以下の内容で更新してください。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import java.util.Set;
import java.util.concurrent.CompletionStage;

@Path("/extension")
public class ExtensionsResource {

    @RestClient
    ExtensionsService extensionsService;


    @GET
    @Path("/id/{id}")
    public Set<Extension> id(String id) {
        return extensionsService.getById(id);
    }

    @GET
    @Path("/id-async/{id}")
    public CompletionStage<Set<Extension>> idAsync(String id) {
        return extensionsService.getByIdAsync(id);
    }
}

呼び出しがノンブロッキングになったため、 idAsync メソッドがイベントループで呼び出されることに注意してください。つまり、ワーカープールのスレッドにオフロードされないので、ハードウェアリソースの使用量を減らすことができます。詳細は、Quarkus REST 実行モデル を参照してください。

非同期メソッドをテストするには、 ExtensionsResourceTest に以下のテストメソッドを追加します。

@Test
public void testExtensionIdAsyncEndpoint() {
    given()
        .when().get("/extension/id-async/io.quarkus:quarkus-rest-client")
        .then()
        .statusCode(200)
        .body("$.size()", is(1),
            "[0].id", is("io.quarkus:quarkus-rest-client"),
            "[0].name", is("REST Client"),
            "[0].keywords.size()", greaterThan(1),
            "[0].keywords", hasItem("rest-client"));
}

Uni 版は非常に似ています。

package org.acme.rest.client;

import io.smallrye.mutiny.Uni;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.Set;

@Path("/extensions")
@RegisterRestClient(configKey = "extensions-api")
public interface ExtensionsService {

    // ...

    @GET
    Uni<Set<Extension>> getByIdAsUni(@QueryParam("id") String id);
}

ExtensionsResource は次のようになります。

package org.acme.rest.client;

import io.smallrye.mutiny.Uni;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import java.util.Set;

@Path("/extension")
public class ExtensionsResource {

    @RestClient
    ExtensionsService extensionsService;


    // ...

    @GET
    @Path("/id-uni/{id}")
    public Uni<Set<Extension>> idUni(String id) {
        return extensionsService.getByIdAsUni(id);
    }
}
Mutiny

前のスニペットでは、Mutinyのリアクティブ型を使用しています。もし慣れていない場合は、まず Mutiny - 直感的なリアクティブプログラミングライブラリ を読んでください。

Uni を返すとき、すべての サブスクリプション は、リモートサービスを呼び出します。つまり、 Uni で再購読してリクエストを再送信するか、以下のように retry を使用することができます。

@RestClient ExtensionsService extensionsService;

// ...

extensionsService.getByIdAsUni(id)
    .onFailure().retry().atMost(10);

CompletionStage を使用する場合は、再試行のためにサービスのメソッドを呼び出す必要があります。この違いは、Mutiny とそのサブスクリプションプロトコルの lazy (遅延) 性の側面から来ています。これについての詳細は Mutiny の ドキュメント を参照してください。

サーバー送信イベント (SSE) のサポート

SSE イベントは、結果の型を io.smallrye.mutiny.Multi と宣言するだけで使用できます。

最も簡単な例

package org.acme.rest.client;

import io.smallrye.mutiny.Multi;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/sse")
@RegisterRestClient(configKey = "some-api")
public interface SseClient {
     @GET
     @Produces(MediaType.SERVER_SENT_EVENTS)
     Multi<String> get();
}

SSE 結果のストリーミングに関係するすべての IO は、ノンブロッキング方式で実行されます。

結果は文字列に限定されません。たとえば、サーバーが各イベントの JSON ペイロードを返すと、Quarkus はそれを Multi で使用される汎用型に自動的にデシリアライズします。

ユーザーは、 org.jboss.resteasy.reactive.client.SseEvent 型を使用して、SSE イベント全体にアクセスすることもできます。

イベントペイロードが Long 値である簡単な例を次に示します。

package org.acme.rest.client;

import io.smallrye.mutiny.Uni;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.reactive.client.SseEvent;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;

@Path("/sse")
@RegisterRestClient(configKey = "some-api")
public interface SseClient {
     @GET
     @Produces(MediaType.SERVER_SENT_EVENTS)
     Multi<SseEvent<Long>> get();
}

イベントのフィルタリング

場合によっては、SSE イベントのストリームに、クライアントから返されるべきではないイベントが含まれることがあります。この例としては、基盤となる TCP 接続を開いたままにするために、サーバーがハートビートイベントを送信することが挙げられます。REST Client は、 @org.jboss.resteasy.reactive.client.SseEventFilter を提供することで、このようなイベントをフィルタリングすることをサポートします。

以下はハートビートイベントをフィルタリングする例です。

package org.acme.rest.client;

import io.smallrye.mutiny.Uni;
import java.util.function.Predicate;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.reactive.client.SseEvent;
import org.jboss.resteasy.reactive.client.SseEventFilter;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;

@Path("/sse")
@RegisterRestClient(configKey = "some-api")
public interface SseClient {

     @GET
     @Produces(MediaType.SERVER_SENT_EVENTS)
     @SseEventFilter(HeartbeatFilter.class)
     Multi<SseEvent<Long>> get();


     class HeartbeatFilter implements Predicate<SseEvent<String>> {

        @Override
        public boolean test(SseEvent<String> event) {
            return !"heartbeat".equals(event.id());
        }
     }
}

カスタムヘッダーのサポート

REST 呼び出しのカスタムヘッダーを指定する方法はいくつかあります。

  • @RegisterClientHeaders アノテーションを用いて ClientHeadersFactory または ReactiveClientHeadersFactory を登録する方法。

  • QuarkusRestClientBuilder.clientHeadersFactory(factory) メソッドを使用して、 ClientHeadersFactory または ReactiveClientHeadersFactory をプログラムで登録する方法。

  • @ClientHeaderParam でヘッダーの値を指定する方法。

  • @HeaderParam でヘッダーの値を指定する方法。

以下のコードは、これらの各手法の使用方法を示しています。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.Set;
import io.quarkus.rest.client.reactive.NotBody;

@Path("/extensions")
@RegisterRestClient
@RegisterClientHeaders(RequestUUIDHeaderFactory.class) (1)
@ClientHeaderParam(name = "my-header", value = "constant-header-value") (2)
@ClientHeaderParam(name = "computed-header", value = "{org.acme.rest.client.Util.computeHeader}") (3)
public interface ExtensionsService {

    @GET
    @ClientHeaderParam(name = "header-from-properties", value = "${header.value}") (4)
    @ClientHeaderParam(name = "header-from-method-param", value = "Bearer {token}") (5)
    Set<Extension> getById(@QueryParam("id") String id, @HeaderParam("jaxrs-style-header") String headerValue, @NotBody String token); (6)
}
1 クラスごとに ClientHeadersFactory は 1 つだけです。これを使用すると、カスタムヘッダーを追加できるだけでなく、既存のヘッダーを変換することもできます。ファクトリーの例については、以下の RequestUUIDHeaderFactory クラスを参照してください。
2 @ClientHeaderParam は、クライアントインターフェイスとメソッドで使用できます。また、一定のヘッダー値を指定できます…​。
3 …​ また、ヘッダーの値を計算するメソッドの名前を指定することもできます。このメソッドは、静的メソッドまたはこのインターフェイス内のデフォルトメソッドのいずれかにすることができます。メソッドは、パラメーターなし、単一の String パラメーター、または単一の io.quarkus.rest.client.reactive.ComputedParamContext パラメーターを取ることができます (これは、メソッドのパラメーターに基づいてヘッダーを計算する必要があるコードに非常に便利で、 @io.quarkus.rest.client.reactive.NotBody と自然に補完し合います)。
4 …​ また、アプリケーションの設定値も使用します。
5 …​ または、逐語的なテキスト、メソッドパラメーター (名前で参照)、設定値 (前述のとおり)、メソッド呼び出し (前述のとおり) の任意の組み合わせでもかまいません。
6 …​ または、通常の Jakarta REST @HeaderParam アノテーション付き引数として

Kotlin を使用する際にデフォルトメソッドを活用する場合は、Java のデフォルトインターフェイス機能を使用するように Kotlin コンパイラーを設定する必要があります。詳細は こちら を参照してください。

ClientHeadersFactory は次のようになります。

package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.core.MultivaluedHashMap;
import jakarta.ws.rs.core.MultivaluedMap;
import java.util.UUID;

@ApplicationScoped
public class RequestUUIDHeaderFactory implements ClientHeadersFactory {

    @Override
    public MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders, MultivaluedMap<String, String> clientOutgoingHeaders) {
        MultivaluedMap<String, String> result = new MultivaluedHashMap<>();
        result.add("X-request-uuid", UUID.randomUUID().toString());
        return result;
    }
}

上記の例で示すように、@Singleton@ApplicationScoped などのスコープ定義アノテーションを付与することで、ClientHeadersFactory の実装を CDI Bean にできます。

${header.value} に値を指定するには、application.properties に次のように記述するだけです。

header.value=value of the header

また、ブロッキング操作を実行できる ClientHeadersFactory のリアクティブなフレーバーも存在します。例えば、次のとおりです。

package org.acme.rest.client;

import io.smallrye.mutiny.Uni;

import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.core.MultivaluedHashMap;
import jakarta.ws.rs.core.MultivaluedMap;
import java.util.UUID;

@ApplicationScoped
public class GetTokenReactiveClientHeadersFactory extends ReactiveClientHeadersFactory {

    @Inject
    Service service;

    @Override
    public Uni<MultivaluedMap<String, String>> getHeaders(
            MultivaluedMap<String, String> incomingHeaders,
            MultivaluedMap<String, String> clientOutgoingHeaders) {
        return Uni.createFrom().item(() -> {
            MultivaluedHashMap<String, String> newHeaders = new MultivaluedHashMap<>();
            // perform blocking call
            newHeaders.add(HEADER_NAME, service.getToken());
            return newHeaders;
        });
    }
}

HTTP Basic 認証を使用する場合、@io.quarkus.rest.client.reactive.ClientBasicAuth アノテーションを使用すると、必要な Authorization ヘッダーをより簡単に設定できます。

非常に簡単な例を次に示します。

@ClientBasicAuth(username = "${service.username}", password = "${service.password}")
public interface SomeClient {

}

ここで、service.usernameservice.password は、呼び出されるサービスへのアクセスを許可するユーザー名とパスワードとして実行時に設定する必要がある設定プロパティーです。

デフォルトヘッダーファクトリー

@RegisterClientHeaders アノテーションは、カスタムファクトリーを指定せずに使用することも可能です。この場合、DefaultClientHeadersFactoryImpl ファクトリーが使用されます。REST リソースから REST クライアント呼び出しを行うと、このファクトリーは org.eclipse.microprofile.rest.client.propagateHeaders 設定プロパティーにリストされているすべてのヘッダーをリソースリクエストからクライアントリクエストへ伝播させます。個々のヘッダー名はコンマで区切られます。

@Path("/extensions")
@RegisterRestClient
@RegisterClientHeaders
public interface ExtensionsService {

    @GET
    Set<Extension> getById(@QueryParam("id") String id);

    @GET
    CompletionStage<Set<Extension>> getByIdAsync(@QueryParam("id") String id);
}
org.eclipse.microprofile.rest.client.propagateHeaders=Authorization,Proxy-Authorization

複数の @Consumes メディアタイプ

REST Client インターフェイスのメソッドには、複数のメディアタイプ値を持つ @Consumes アノテーションが付与されている場合があります。次に例を示します。

@Path("/orders")
@RegisterRestClient
public interface OrderService {

    record OrderReference(String orderReference) {
    };

    @POST
    @Consumes({"application/json", "application/yaml"}) (1)
    Response addOrderReference(OrderReference orderReference);
}
1 REST サーバーは、OrderReference 表現を JSON または YAML 形式のいずれかで受け入れます。

REST Client は、POST /orders リクエストに Content-Type を設定する必要があります。複数のメディアタイプ値を持つ @Consumes を検出すると、それらをソートし、最初のメディアタイプを Content-Type の値として選択します。リストされているすべての @Consumes の値が REST サーバーでサポートされると予想されるため、OrderService#addOrderReference のような呼び出しを行うクライアントコードには影響を与えないはずです。

OrderService インターフェイスの定義に従って、application/yaml など別の Content-Type を設定したい場合は、リクエストのカスタマイズ セクションで説明されているようにカスタム ClientRequestFiler を登録してください。

@Provider
public class RestClientContentTypeRequestFilter implements ClientRequestFilter {

    @Override
    public void filter(ClientRequestContext rc) throws IOException {
        String contentType = rc.getHeaderString("Content-Type"));
        if ("application/json".equals(contentType)) {
            rc.getHeaders().putSingle("Content-Type", "application/yaml");
        }
    }

}

リクエストのカスタマイズ

REST Client は、フィルターを介してサーバーに送信される最終リクエストのさらなるカスタマイズをサポートします。フィルターは、ClientRequestFilter または ResteasyReactiveClientRequestFilter のいずれかのインターフェイスを実装する必要があります。

リクエストをカスタマイズする簡単な例としては、カスタムヘッダーを追加することが挙げられます。

@Provider
public class TestClientRequestFilter implements ClientRequestFilter {

    @Override
    public void filter(ClientRequestContext requestContext) {
        requestContext.getHeaders().add("my_header", "value");
    }
}

次に、@RegisterProvider アノテーションを使用してフィルターを登録できます。

@Path("/extensions")
@RegisterProvider(TestClientRequestFilter.class)
public interface ExtensionsService {

    // ...
}

または、プログラムで .register() メソッドを使用します。

QuarkusRestClientBuilder.newBuilder()
    .register(TestClientRequestFilter.class)
    .build(ExtensionsService.class)

フィルターでの jakarta.ws.rs.ext.Providers インスタンスのインジェクション

jakarta.ws.rs.ext.Providers は、現在のクライアントのプロバイダーインスタンスを検索する必要がある場合に役立ちます。

フィルター内でリクエストコンテキストから Providers インスタンスを取得する方法は次のとおりです。

@Provider
public class TestClientRequestFilter implements ClientRequestFilter {

    @Override
    public void filter(ClientRequestContext requestContext) {
        Providers providers = ((ResteasyReactiveClientRequestContext) requestContext).getProviders();
        // ...
    }
}

または、ClientRequestFilter インターフェイスの代わりに ResteasyReactiveClientRequestFilter インターフェイスを実装して、ResteasyReactiveClientRequestContext コンテキストを直接提供することもできます。

@Provider
public class TestClientRequestFilter implements ResteasyReactiveClientRequestFilter {

    @Override
    public void filter(ResteasyReactiveClientRequestContext requestContext) {
        Providers providers = requestContext.getProviders();
        // ...
    }
}

Jackson 固有の機能

REST Client Jackson での ObjectMapper のカスタマイズ

REST Client は、@ClientObjectMapper アノテーションを使用して、クライアント専用のカスタム ObjectMapper を追加することをサポートします。

簡単な例として、REST Client Jackson エクステンションにカスタム ObjectMapper を提供する方法を次に示します。

@Path("/extensions")
@RegisterRestClient
public interface ExtensionsService {

    @GET
    Set<Extension> getById(@QueryParam("id") String id);

    @ClientObjectMapper (1)
    static ObjectMapper objectMapper(ObjectMapper defaultObjectMapper) { (2)
        return defaultObjectMapper.copy() (3)
                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
                .disable(DeserializationFeature.UNWRAP_ROOT_VALUE);
    }
}
1 このメソッドには @ClientObjectMapper アノテーションを付ける必要があります。
2 これは静的メソッドである必要があります。また、パラメーター defaultObjectMapper は CDI を介して解決されます。見つからない場合、実行時に例外がスローされます。
3 この例では、デフォルトのオブジェクトマッパーのコピーを作成しています。デフォルトのオブジェクトマッパーは 絶対に 変更せず、代わりにコピーを作成してください。

@JsonView サポート

Jakarta REST メソッドは、返される POJO のシリアライズをメソッドごとにカスタマイズするために、@JsonView アノテーションを付けることができます。これは例を用いて説明するのが最も分かりやすいでしょう。

@JsonView の典型的な使用法は、特定のメソッドで特定のフィールドを非表示にすることです。その流れで、2 つのビューを定義しましょう。

public class Views {

    public static class Public {
    }

    public static class Private extends Public {
    }
}

シリアライズ中に一部のフィールドを非表示にしたい User POJO があると仮定しましょう。その簡単な例は次のとおりです。

public class User {

    @JsonView(Views.Private.class)
    public int id;

    @JsonView(Views.Public.class)
    public String name;
}

REST Client は、REST API へのコンテンツの送信と、REST API からのデータ取得の両方で @JsonView をサポートします。

    @Path("/users")
    @RegisterRestClient
    public interface UserClient {
        @GET
        @Path("/{id}")
        @Produces(MediaType.APPLICATION_JSON)
        @JsonView(Views.Public.class)
        User get(@RestPath String id);

        @POST
        @Consumes(MediaType.APPLICATION_JSON)
        Response create(@JsonView(Views.Public.class) User user);
    }

上記のコードでは、get メソッドは id が常に nullUser を返し、create メソッドは REST API に送信する JSON に id を含めません。

例外処理

MicroProfile REST Client 仕様では、HTTP レスポンスを例外に変換することを目的とした org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper が導入されています。

上記で説明した ExtensionsService にこのような ResponseExceptionMapper を実装する簡単な例は次のとおりです。

public class MyResponseExceptionMapper implements ResponseExceptionMapper<RuntimeException> {

    @Override
    public RuntimeException toThrowable(Response response) {
        if (response.getStatus() == 500) {
            return new RuntimeException("The remote service responded with HTTP 500");
        }
        return null;
    }
}

ResponseExceptionMapper は、ResponseExceptionMapper の実装が呼び出される優先度を決定するために使用される getPriority メソッドも定義します (getPriority の値が小さい実装が最初に呼び出されます)。toThrowable が例外を返すと、その例外がスローされます。null が返された場合、チェーン内の次の ResponseExceptionMapper の実装が呼び出されます (存在する場合)。

上記のクラスは、どの REST Client でも自動的に使用されません。アプリケーションのすべての REST Client で利用できるようにするには、クラスに @Provider アノテーションを付ける必要があります (quarkus.rest-client.provider-autodiscoveryfalse に設定されていない限り)。別の方法として、例外処理クラスを特定の REST Client インターフェイスにのみ適用する必要がある場合は、インターフェイスに @RegisterProvider(MyResponseExceptionMapper.class) とアノテーションを付けるか、適切な quarkus.rest-client 設定グループの providers 設定プロパティーを使用して設定で登録できます。

@ClientExceptionMapper の使用

400 以上の HTTP レスポンスコードを変換する簡単な方法は、@ClientExceptionMapper アノテーションを使用することです。

上記で定義した ExtensionsService REST Client インターフェイスの場合、@ClientExceptionMapper の使用例は次のようになります。

@Path("/extensions")
@RegisterRestClient
public interface ExtensionsService {

    @GET
    Set<Extension> getById(@QueryParam("id") String id);

    @GET
    CompletionStage<Set<Extension>> getByIdAsync(@QueryParam("id") String id);

    @ClientExceptionMapper
    static RuntimeException toException(Response response) {
        if (response.getStatus() == 500) {
            return new RuntimeException("The remote service responded with HTTP 500");
        }
        return null;
    }
}

当然、この処理は REST Client ごとに行われます。@ClientExceptionMapper は、priority 属性が設定されていない場合、デフォルトの優先度を使用し、すべてのハンドラーを順番に呼び出す通常のルールが適用されます。

@ClientExceptionMapper でアノテーションされたメソッドは、java.lang.reflect.Method パラメーターも受け取ることができます。これは、例外マッピングコードが、呼び出されて例外マッピングコードが起動された REST Client メソッドを知る必要がある場合に役立ちます。

例外マッパーでの @Blocking アノテーションの使用

REST Client メソッドの戻り値の型として InputStream の使用が妥当な場合 (大量のデータを読み取る必要がある場合など) は、次のとおりです。

@Path("/echo")
@RegisterRestClient
public interface EchoClient {

    @GET
    InputStream get();
}

これは期待どおりに動作しますが、この InputStream オブジェクトをカスタム例外マッパーで読み取ろうとすると、 BlockingNotAllowedException 例外が発生します。これは、 ResponseExceptionMapper クラスがデフォルトで Event Loop スレッドエグゼキューターで実行され、IO 操作を実行できないためです。

例外マッパーをブロッキングにするには、例外マッパーに @Blocking アノテーションを付けます。

@Provider
@Blocking (1)
public class MyResponseExceptionMapper implements ResponseExceptionMapper<RuntimeException> {

    @Override
    public RuntimeException toThrowable(Response response) {
        if (response.getStatus() == 500) {
            response.readEntity(String.class); (2)
            return new RuntimeException("The remote service responded with HTTP 500");
        }
        return null;
    }
}
1 @Blocking アノテーションにより、MyResponseExceptionMapper 例外マッパーはワーカースレッドプールで実行されます。
2 ワーカースレッドプールでマッパーを実行しているため、エンティティの読み取りが許可されるようになりました。

なお、@ClientExceptionMapper を使用する場合、 @Blocking アノテーションを使用することも可能です:

@Path("/echo")
@RegisterRestClient
public interface EchoClient {

    @GET
    InputStream get();

    @ClientExceptionMapper
    @Blocking
    static RuntimeException toException(Response response) {
        if (response.getStatus() == 500) {
            response.readEntity(String.class);
            return new RuntimeException("The remote service responded with HTTP 500");
        }
        return null;
    }
}

デフォルトマッパーの無効化

REST Client の仕様により、HTTP ステータスコードが 400 より大きい場合に例外をスローするデフォルトの例外マッパーが含まれています。この動作はクライアントが通常のオブジェクトを返す場合には問題ありませんが、クライアントが jakarta.ws.rs.core.Response を返す必要がある場合 (呼び出し元が HTTP ステータスコードの処理方法を決定できるようにすることを意図している場合) には、ほとんど直感的ではありません。

このため、REST Client には、宣言的な方法で REST クライアントを使用する際にデフォルトのマッパーを無効にするために使用できる disable-default-mapper という設定プロパティーが含まれています。

例えば、次のようなクライアントの場合:

    @Path("foo")
    @RegisterRestClient(configKey = "bar")
    public interface Client {
        @GET
        Response get();
    }

デフォルトの例外マッパーは、 quarkus.rest-client.bar.disable-default-mapper=true を設定して、キー bar で設定された REST Client の例外マッパーを無効にすることで無効にできます。

REST Client を作成するためのプログラム的なアプローチを使用する場合、 QuarkusRestClientBuilder は、同じ機能を提供する disableDefaultMapper という名前のメソッドを提供します。

マルチパートフォームのサポート

マルチパートメッセージの送信

REST Client を使用すると、データをマルチパートフォームとして送信できます。このようにして、例えばファイルを効率的に送信できます。

データをマルチパートフォームとして送信するには、通常の @RestForm (または @FormParam ) アノテーションを使用します:

    @POST
    @Path("/binary")
    String sendMultipart(@RestForm File file, @RestForm String otherField);

FilePathbyte[]Buffer、または FileUpload として指定されたパラメーターはファイルとして送信され、デフォルトでは application/octet-stream MIME 型になります。その他の @RestForm パラメーター型はデフォルトで text/plain MIME 型になります。これらのデフォルトは、 @PartType アノテーションでオーバーライドできます。

当然ながら、これらのパラメーターを含むクラスにまとめることも可能です:

    public static class Parameters {
        @RestForm
        File file;

        @RestForm
        String otherField;
    }

    @POST
    @Path("/binary")
    String sendMultipart(Parameters parameters);

FilePathbyte[]Buffer、または FileUpload 型の @RestForm パラメーター、および @PartType でアノテーションが付けられたパラメーターは、 @Consumes が指定されていない場合、自動的にメソッドに @Consumes(MediaType.MULTIPART_FORM_DATA) が付与されます。

マルチパートではない @RestForm パラメーターがある場合は、 @Consumes(MediaType.APPLICATION_FORM_URLENCODED) になります。

フォームデータのエンコードには、いくつかのモードがあります。デフォルトでは、REST Client は RFC1738 を使用します。クライアントレベルで、 io.quarkus.rest.client.multipart-post-encoder-mode RestBuilder 設定プロパティーを HttpPostRequestEncoder.EncoderMode の選択した値に設定するか、 application.propertiesquarkus.rest-client.multipart-post-encoder-mode を指定して、モードをオーバーライドできます。後者は @RegisterRestClient アノテーションで作成されたクライアントに対してのみ機能することに注意してください。利用可能なすべてのモードは、Netty ドキュメント に記載されています。

また、 @PartType アノテーションを指定することで、JSON のマルチパートも送信できます:

    public static class Person {
        public String firstName;
        public String lastName;
    }

    @POST
    @Path("/json")
    String sendMultipart(@RestForm @PartType(MediaType.APPLICATION_JSON) Person person);

プログラムによるマルチパートフォームの作成

マルチパートコンテンツをプログラムで構築する必要がある場合、REST Client は、次のように REST Client で使用できる ClientMultipartForm を提供します。

public interface MultipartService {

  @POST
  @Path("/multipart")
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  @Produces(MediaType.APPLICATION_JSON)
  Map<String, String> multipart(ClientMultipartForm dataParts);
}

このクラスとサポートされているメソッドの詳細は、ClientMultipartForm の javadoc を参照してください。

受信したマルチパートオブジェクトのクライアントリクエストへの変換

ClientMultipartForm を作成する良い例は、サーバーの MultipartFormDataInput (Quarkus REST によって受信されたマルチパートリクエストを表す) から作成されるものです。その目的は、任意の変更を許可しながらリクエストをダウンストリームに伝播することです。

public ClientMultipartForm buildClientMultipartForm(MultipartFormDataInput inputForm) (1)
    throws IOException {
  ClientMultipartForm multiPartForm = ClientMultipartForm.create(); (2)
  for (Entry<String, Collection<FormValue>> attribute : inputForm.getValues().entrySet()) {
    for (FormValue fv : attribute.getValue()) {
      if (fv.isFileItem()) {
        final FileItem fi = fv.getFileItem();
        String mediaType = Objects.toString(fv.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE),
            MediaType.APPLICATION_OCTET_STREAM);
        if (fi.isInMemory()) {
          multiPartForm.binaryFileUpload(attribute.getKey(), fv.getFileName(),
              Buffer.buffer(IOUtils.toByteArray(fi.getInputStream())), mediaType); (3)
        } else {
          multiPartForm.binaryFileUpload(attribute.getKey(), fv.getFileName(),
              fi.getFile().toString(), mediaType); (4)
        }
      } else {
        multiPartForm.attribute(attribute.getKey(), fv.getValue(), fv.getFileName()); (5)
      }
    }
  }
  return multiPartForm;
}
1 MultipartFormDataInput は、受信したマルチパートリクエストを表す Quarkus REST (Server) 型です。
2 ClientMultipartForm が作成されました。
3 メモリー内のファイル属性を表すリクエスト属性に対して FileItem 属性が作成されます。
4 ファイルシステムに保存されたファイル属性を表すリクエスト属性に対して FileItem 属性が作成されます。
5 FileItem でない場合、ファイル以外の属性が ClientMultipartForm に直接追加されます。

同様に、受信したサーバーのマルチパート要求が既知で、次のようになる場合:

public class Request { (1)

  @RestForm("files")
  @PartType(MediaType.APPLICATION_OCTET_STREAM)
  List<FileUpload> files;

  @RestForm("jsonPayload")
  @PartType(MediaType.TEXT_PLAIN)
  String jsonPayload;
}

ClientMultipartForm は次のように簡単に作成できます。

public ClientMultipartForm buildClientMultipartForm(Request request) { (1)
  ClientMultipartForm multiPartForm = ClientMultipartForm.create();
  multiPartForm.attribute("jsonPayload", request.getJsonPayload(), "jsonPayload"); (2)
  request.getFiles().forEach(fu -> {
    multiPartForm.fileUpload(fu); (3)
  });
  return multiPartForm;
}
1 サーバー部分が受け入れるリクエストを表す Request
2 jsonPayload 属性が ClientMultipartForm に直接追加されます。
3 リクエストの FileUpload から fileUpload が作成されます。

同じ名前を使用するマルチパートデータを送信する場合、クライアントとサーバーが同じマルチパートエンコーダーモードを使用していないと、問題が発生する可能性があります。デフォルトでは、REST Client は RFC1738 を使用しますが、状況によっては、クライアントを HTML5 または RFC3986 モードで設定する必要がある場合があります。

この設定は、 quarkus.rest-client.multipart-post-encoder-mode 設定プロパティーを介して実現できます。

マルチパートメッセージの受信

REST Client は、マルチパートメッセージの受信もサポートしています。送信と同様に、マルチパートレスポンスを解析するには、レスポンスデータを記述するクラスを作成する必要があります。以下に例を示します。

public class FormDto {
    @RestForm (1)
    @PartType(MediaType.APPLICATION_OCTET_STREAM)
    public File file;

    @FormParam("otherField") (2)
    @PartType(MediaType.TEXT_PLAIN)
    public String textProperty;
}
1 省略形の @RestForm アノテーションを使用して、フィールドをマルチパートフォームの一部にします
2 標準の @FormParam も使用できます。これはマルチパートパートの名前を上書きできます。

次に、呼び出しに対応するインターフェイスメソッドを作成し、 FormDto を返すようにします:

    @GET
    @Produces(MediaType.MULTIPART_FORM_DATA)
    @Path("/get-file")
    FormDto data receiveMultipart();

現時点では、マルチパート応答のサポートには次の制限があります:

  • マルチパート応答で送信されたファイルは、 FilePath、および FileDownload にのみ解析できます。

  • 応答型の各フィールドには @PartType アノテーションを付ける必要があります。このアノテーションのないフィールドは無視されます。

REST Client は、マルチパートの戻り値の型として使用されるクラスを事前に認識する必要があります。 multipart/form-data を生成するインターフェイスメソッドがある場合、戻り値の型は自動的に検出されます。ただし、 ClientBuilder API を使用して応答をマルチパートとして解析する場合は、DTO クラスに @MultipartForm アノテーションを付ける必要があります。

ダウンロードしたファイルは自動的に削除されず、多くのディスク領域を占有する可能性があります。作業が終わったら、ファイルを削除することを検討してください。

マルチパート混合 / OData の利用

アプリケーションが、 OData と呼ばれる特別なプロトコルを使用してエンタープライズシステム (CRM システムなど) と対話する必要があることは珍しくありません。このプロトコルは基本的に、REST Client で動作するためにいくつかのグルーコードを必要とするカスタム HTTP Content-Type を使用します (本体の作成は完全にアプリケーション次第であり、REST Client はあまり役に立ちません)。

例は次のようになります:

@Path("/crm")
@RegisterRestClient
public interface CRMService {

    @POST
    @ClientHeaderParam(name = "Content-Type", value = "{calculateContentType}")  (1)
    String performBatch(@HeaderParam("Authorization") String accessToken, @NotBody String batchId, String body); (2)

    default String calculateContentType(ComputedParamContext context) {
        return "multipart/mixed;boundary=batch_" + context.methodParameters().get(1).value(); (3)
    }
}

コードでは次の要素を使用します。

1 @ClientHeaderParam(name = "Content-Type", value = "{calculateContentType}") は、インターフェイスの calculateContentType デフォルトメソッドを呼び出して Content-Type ヘッダーが作成されるようにします。
2 前述のパラメーターは、HTTP ヘッダーの構築を支援するためにのみ使用されるため、 @NotBody アノテーションを付ける必要があります。
3 context.methodParameters().get(1).value() により、 calculateContentType メソッドは REST Client メソッドに渡される適切なメソッドパラメーターを取得できるようになります。

前述したように、サービスの要件に準拠するには、アプリケーションコードによって body パラメーターを適切に作成する必要があります。

圧縮メッセージの受信

REST Client は GZIP を使用した圧縮メッセージの受信もサポートしており、設定で有効にすることができます。この機能が有効で、サーバがヘッダー Content-Encoding: gzip を含む応答を返すと、REST Client は自動的にコンテンツをデコードし、メッセージの処理を進めます。

設定の例は次のようになります:

# global configuration is used for all clients
quarkus.rest-client.enable-compression=true

# per-client configuration overrides the global settings for a specific client
quarkus.rest-client.my-client.enable-compression=true

RESTクライアント固有のプロパティが設定されていない場合、RESTクライアントはQuarkus全体の quarkus.http.enable-compression 設定プロパティ(デフォルトは false )にフォールバックします。

プロキシーサポート

REST Client はプロキシーを介したリクエストの送信をサポートしています。JVM のプロキシー設定に依存することもできますが、REST Client を使用すると、デフォルトのプロキシーと、クライアントが参照できる任意の数の名前付きプロキシー設定を定義できます。

プロキシー設定はプロキシーレジストリーで一元管理されます。プロキシーは quarkus.proxy 設定ルートの下で設定します。

グローバルプロキシー設定

明示的に名前付きプロキシー設定を参照しないすべての REST Client で使用されるデフォルトのプロキシー設定を定義できます。

quarkus.proxy.host=localhost
quarkus.proxy.port=8182
quarkus.proxy.username=username
quarkus.proxy.password=password
quarkus.proxy.non-proxy-hosts=my.company.com

quarkus.rest-client.my-client.url=http://example.com/api

この設定により、 my-client を含むすべての REST Client は、提供されたクレデンシャルで localhost:8182 のプロキシーを使用するようになります。

名前付きプロキシー設定

名前付きプロキシー設定を定義し、特定の REST Client でそれらを使用させることができます。

quarkus.proxy.my-proxy.host=localhost
quarkus.proxy.my-proxy.port=8183
quarkus.proxy.my-proxy.username=username
quarkus.proxy.my-proxy.password=password

quarkus.rest-client.client1.proxy-configuration-name=my-proxy (1)
quarkus.rest-client.client1.url=http://c1.example.com/api

quarkus.rest-client.client2.url=http://c2.example.com/api (2)
1 client1my-proxy プロキシー設定を使用するように構成されています。
2 client2 はプロキシー設定名を指定しないため、デフォルトのプロキシー設定が定義されていない限り、プロキシーを使用しません。

クレデンシャルプロバイダーの使用

quarkus.proxy 設定に加えて、REST Client は Quarkus Credentials Provider からプロキシーのクレデンシャルを取得できます。詳細は Credentials Provider を参照してください。

quarkus.proxy.baby-proxy.host=localhost (1)
quarkus.proxy.baby-proxy.port=3838

quarkus.proxy.credentials-provider.name=credential (2)
quarkus.proxy.credentials-provider.bean-name=credentialBean
quarkus.proxy.credentials-provider.username-key=userKey
quarkus.proxy.credentials-provider.password-key=passwordKey
1 ユーザー名とパスワードなしで、名前付きプロキシー設定 baby-proxy を定義します。
2 プロキシーのユーザー名とパスワードを取得するように Credentials Provider を設定します。
quarkus.proxy.password (グローバル用) または quarkus.proxy.<named>.password (名前付き用) が設定されていない場合、Credentials Provider は使用されません。

開発モードのローカルプロキシー

開発モードで REST クライアントを使用する際、Quarkus はパススループロキシーを立ち上げる機能を備えており、これを Wireshark (または類似のツール) のターゲットとして使用することで、REST クライアントから発信されるすべてのトラフィックをキャプチャーすることができます (特に REST Client が HTTPS サービスに対して使用される場合に有用です)。

この機能は、プロキシーが必要なクライアントに対応する configKey の enable-local-proxy 設定オプションを設定するだけで有効化できます。 以下に例を示します。

quarkus.rest-client.my-client.enable-local-proxy=true

REST クライアントが設定キーを使用しない場合 (たとえば、 QuarkusRestClientBuilder を介してプログラムで作成される場合など)、代わりにクラス名を使用できます。 以下に例を示します。

quarkus.rest-client."org.acme.SomeClient".enable-local-proxy=true

プロキシーがリッスンしているポートは、起動ログで確認できます。エントリーの例は次のとおりです。

Started HTTP proxy server on http://localhost:38227 for REST Client 'org.acme.SomeClient'

アプリケーションのパッケージ化と実行

次のコマンドでアプリケーションを実行します。

コマンドラインインタフェース
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

このエクステンションに関する基本的な情報を含む JSON オブジェクトが表示されるはずです。

いつものように、アプリケーションは以下の方法でパッケージ化されます。

コマンドラインインタフェース
quarkus build
Maven
./mvnw install
Gradle
./gradlew build

そして、 java -jar target/quarkus-app/quarkus-run.jar で実行されます。

次のようにネイティブ実行可能ファイルを生成することもできます。

コマンドラインインタフェース
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true

トラフィックの記録

REST Client は、送信したリクエストと受信したレスポンスをログに記録できます。 ロギングを有効にするには、 application.propertiesquarkus.rest-client.logging.scope プロパティを追加し、次のように設定します:

  • リクエストと応答の内容をログに記録する request-response 、または

  • all は、基礎となるライブラリーの低レベルのロギングも有効にします。

HTTP メッセージには大きな本文が含まれる可能性があるため、ログに記録される本文の文字数を制限します。デフォルトの制限は 100 ですが、 quarkus.rest-client.logging.body-limit を指定することで変更できます。

機密性の高いリクエストおよびレスポンスヘッダーの値は、 quarkus.rest-client.logging.masked-headers を使用してマスクできます。設定されたヘッダーの値は、ログで <hidden> に置き換えられます。

デフォルトのマスク済みヘッダー

quarkus.rest-client.logging.masked-headers のデフォルト値 (AuthorizationCookie) は、値を明示的に設定すると置き換えられます。 マスクを維持する必要がある場合は、それらを 明示的に 含める必要があります。

これらの設定プロパティーは、CDI によって注入されたすべてのクライアントに対してグローバルに機能します。 特定の宣言型クライアントのロギングを設定する場合は、 quarkus.rest-client."client".logging.* プロパティーとも呼ばれる、名前付き "client" プロパティーを指定して設定する必要があります。

ロギング設定の例:

quarkus.rest-client.logging.scope=request-response
quarkus.rest-client.logging.body-limit=50
quarkus.rest-client.logging.masked-headers=Authorization,Cookie,x-super-secret

quarkus.rest-client.extensions-api.logging.scope=all

REST Client はデフォルトの ClientLogger 実装を使用します。この実装は、カスタム実装に置き換えることができます。

QuarkusRestClientBuilder を使用してプログラムでクライアントを設定する場合、 ClientLoggerclientLogger メソッドで設定されます。

@RegisterRestClient を使用する宣言型クライアントの場合、 ClientLogger を実装する CDI Bean を提供するだけで、そのロガーをクライアントが使用できるようになります。

メトリクス

すべての宣言型 REST Client インスタンスは、http.clients プレフィックスを使用してメトリクスを生成します。さらに、メトリクスには clientName というタグが含まれており、これはクライアントのコンフィグキー (@RegisterRestClient アノテーションの configKey プロパティーで指定) に対応します。

プログラムで作成された REST クライアントのメトリクスを有効にするには、次のスニペットを使用できます。

var builder = QuarkusRestClientBuilder.newBuilder();

// use the builder to configure the client

// now configure a customizer that sets the metrics name
builder.httpClientOptionsCustomizer(new Consumer<>() {
    @Override
    public void accept(HttpClientOptions httpClientOptions) {
        String metricsName = httpClientOptions.getMetricsName();
        if (metricsName == null || metricsName.isEmpty()) {
            httpClientOptions.setMetricsName("rest-client|" + "someName"); // the 'rest-client|' prefix is absolutely necessary here
        }
    }
});

テストのためのクライアントのモック

@RestClient アノテーションが挿入されたクライアントを使用する場合、テスト用に簡単にモックできます。これは Mockito の @InjectMock または QuarkusMock を使用して行うことができます。

このセクションでは、クライアントをモックに置き換える方法を示します。Quarkus でモッキングがどのように機能するかをより深く理解したい場合は、 CDI Bean のモック に関するブログ投稿を参照してください。

@QuarkusIntegrationTest を使用している場合、モッキングは機能しません。

次のクライアントがあると仮定します。

package io.quarkus.it.rest.client.main;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;


@Path("/")
@RegisterRestClient
public interface Client {
    @GET
    String get();
}

InjectMock によるモック

テスト用のクライアントをモックする最も簡単なアプローチは、Mockito と @InjectMock を使用することです。

まず、以下の依存関係をアプリケーションに追加します。

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-junit-mockito</artifactId>
    <scope>test</scope>
</dependency>
build.gradle
testImplementation("io.quarkus:quarkus-junit-mockito")

次に、テストで @InjectMock を使用して、モックを作成して挿入できます。

package io.quarkus.it.rest.client.main;

import static org.mockito.Mockito.when;

import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class InjectMockTest {

    @InjectMock
    @RestClient
    Client mock;

    @BeforeEach
    public void setUp() {
        when(mock.get()).thenReturn("MockAnswer");
    }

    @Test
    void doTest() {
        // ...
    }
}

QuarkusMock によるモック

Mockito がニーズを満たさない場合は、QuarkusMock を使用してプログラムでモックを作成できます。例:

package io.quarkus.it.rest.client.main;

import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusMock;
import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class QuarkusMockTest {

    @BeforeEach
    public void setUp() {
        Client customMock = new Client() { (1)
            @Override
            public String get() {
                return "MockAnswer";
            }
        };
        QuarkusMock.installMockForType(customMock, Client.class, RestClient.LITERAL); (2)
    }
    @Test
    void doTest() {
        // ...
    }
}
1 ここでは、手動で作成したクライアントインターフェースの実装を使用して、実際のクライアントを置き換えます。
2 RestClient.LITERALinstallMockForType メソッドの最後の引数として渡す必要があることに注意してください。

テストにモック HTTP サーバーを使用

テストを実行するモック HTTP サーバーを設定することは、一般的なテストパターンです。このようなサーバーの例としては、WiremockHoverfly があります。このセクションでは、上で開発した ExtensionsService をテストするために Wiremock をどのように活用できるかを示します。

まず、Wiremock をテストの依存関係として追加する必要があります。Maven プロジェクトの場合、次のようになります。

pom.xml
<dependency>
    <groupId>org.wiremock</groupId>
    <artifactId>wiremock</artifactId>
    <scope>test</scope>
    <version>${wiremock.version}</version> (1)
</dependency>
1 適切な Wiremock バージョンを使用してください。利用可能なすべてのバージョンは こちら で見つけることができます。
build.gradle
testImplementation("org.wiremock:wiremock:$wiremockVersion") (1)
1 適切な Wiremock バージョンを使用してください。利用可能なすべてのバージョンは こちら で見つけることができます。

Quarkus テストを実行する前にサービスを開始する必要がある場合、Quarkus テストでは、@io.quarkus.test.common.QuarkusTestResource アノテーションを利用して、サービスを開始し、Quarkus が使用する設定値を供給できる io.quarkus.test.common.QuarkusTestResourceLifecycleManager を指定します。

@QuarkusTestResource の詳細については、ドキュメントのこの部分 を参照してください。

WiremockExtensions という名前の QuarkusTestResourceLifecycleManager の実装を次のように作成します。

package org.acme.rest.client;

import java.util.Map;

import com.github.tomakehurst.wiremock.WireMockServer;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;

import static com.github.tomakehurst.wiremock.client.WireMock.*; (1)

public class WireMockExtensions implements QuarkusTestResourceLifecycleManager {  (2)

    private WireMockServer wireMockServer;

    @Override
    public Map<String, String> start() {
        wireMockServer = new WireMockServer();
        wireMockServer.start(); (3)

        wireMockServer.stubFor(get(urlEqualTo("/extensions?id=io.quarkus:quarkus-rest-client"))   (4)
                .willReturn(aResponse()
                        .withHeader("Content-Type", "application/json")
                        .withBody(
                            "[{" +
                            "\"id\": \"io.quarkus:quarkus-rest-client\"," +
                            "\"name\": \"REST Client\"" +
                            "}]"
                        )));

        wireMockServer.stubFor(get(urlMatching(".*")).atPriority(10).willReturn(aResponse().proxiedFrom("https://stage.code.quarkus.io/api")));   (5)

        return Map.of("quarkus.rest-client.\"org.acme.rest.client.ExtensionsService\".url", wireMockServer.baseUrl()); (6)
    }

    @Override
    public void stop() {
        if (null != wireMockServer) {
            wireMockServer.stop();  (7)
        }
    }
}
1 Wiremock パッケージのメソッドを静的にインポートすることで、テストを読みやすくすることができます。
2 start メソッドは、テストが実行される前に Quarkus によって呼び出され、テスト実行中に適用される設定プロパティーの Map を返します。
3 Wiremock の起動。
4 /extensions?id=io.quarkus:quarkus-rest-client への呼び出しに対して特定の既定のレスポンスを返すように Wiremock を設定してスタブします。
5 スタブ化されていないすべての HTTP 呼び出しは、実際のサービスを呼び出すことで処理されます。これはデモンストレーション目的で行われており、実際のテストで通常発生することではありません。
6 start メソッドはテストに適用される設定を返すので、ExtensionsService の実装で使用されるベース URL を制御する rest-client プロパティーを、Wiremock が着信リクエストをリッスンするベース URL に設定します。
7 すべてのテストが完了したら、Wiremock をシャットダウンします。

ExtensionsResourceTest テストクラスは次のようにアノテーションを付ける必要があります。

@QuarkusTest
@QuarkusTestResource(WireMockExtensions.class)
public class ExtensionsResourceTest {

}

@QuarkusTestResourceExtensionsResourceTest だけでなく、すべてのテストに適用されます。

既知の制限

REST Client エクステンションは RESTEasy Client エクステンションのドロップイン代替となることを目指していますが、いくつかの違いと制限があります。

  • 新しいエクステンションのクライアントのデフォルトスコープは @ApplicationScoped ですが、quarkus-resteasy-client はデフォルトで @Dependent です。この動作を変更するには、quarkus.rest-client.scope プロパティーを完全修飾スコープ名に設定します。

  • SSLContext を設定することはできません。

  • ExecutorService の設定など、非ブロッキング実装には意味をなさないいくつかのことが機能しません。

留意すべきインポート

同時リクエスト

REST Client は、ターゲット REST サービスに対して使用される必要な HTTP 接続を最小限に抑えるため、デフォルトサイズ 50 の Vert.x HTTP 接続プールを使用します。これは妥当なデフォルトですが、特定のシナリオでは制限が厳しすぎる場合があります。そのような場合、quarkus.rest-client."some-client".connection-pool-size 設定プロパティーを使用できます。

設定リファレンス

ビルド時に固定される設定プロパティー - 他のすべての設定プロパティーは実行時にオーバーライド可能

Configuration property

デフォルト

By default, RESTEasy Reactive uses text/plain content type for String values and application/json for everything else.

MicroProfile Rest Client spec requires the implementations to always default to application/json. This build item disables the "smart" behavior of RESTEasy Reactive to comply to the spec

Environment variable: QUARKUS_REST_CLIENT_DISABLE_SMART_PRODUCES

Show more

boolean

false

Whether providers (filters, etc.) annotated with jakarta.ws.rs.ext.Provider should be automatically registered for all the clients in the application.

Environment variable: QUARKUS_REST_CLIENT_PROVIDER_AUTODISCOVERY

Show more

boolean

true

ビルド時に固定される設定プロパティー - 他のすべての設定プロパティーは実行時にオーバーライド可能

Configuration property

デフォルト

The CDI scope to use for injection. This property can contain either a fully qualified class name of a CDI scope annotation (such as "jakarta.enterprise.context.ApplicationScoped") or its simple name (such as "ApplicationScoped"). By default, this is not set which means the interface is not registered as a bean unless it is annotated with RegisterRestClient. If an interface is not annotated with RegisterRestClient and this property is set, then Quarkus will make the interface a bean of the configured scope.

Environment variable: QUARKUS_REST_CLIENT_SCOPE

Show more

string

If true, the extension will automatically remove the trailing slash in the paths if any. This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_REMOVES_TRAILING_SLASH

Show more

boolean

true

Mode in which the form data are encoded. Possible values are HTML5, RFC1738 and RFC3986. The modes are described in the Netty documentation

By default, Rest Client Reactive uses RFC1738.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_MULTIPART_POST_ENCODER_MODE

Show more

string

The name of the proxy configuration to use; ignored if quarkus.rest-client.proxy-address is set.

If not set and the default proxy configuration is configured (quarkus.proxy.*) then that will be used. If the proxy configuration name is set, the configuration from quarkus.proxy.<name>.* will be used. If the proxy configuration name is set, but no proxy configuration is found with that name, then an error will be thrown at runtime.

Can be overwritten by client-specific settings.

Use the value none to disable using the default configuration defined via quarkus.proxy.*.

Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency) does not support this property.

Environment variable: QUARKUS_REST_CLIENT_PROXY_CONFIGURATION_NAME

Show more

string

A timeout in milliseconds that REST clients should wait for a response from the remote endpoint.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_READ_TIMEOUT

Show more

30000

If true, the REST clients will not provide additional contextual information (like REST client class and method names) when exception occurs during a client invocation.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_DISABLE_CONTEXTUAL_ERROR_MESSAGES

Show more

boolean

false

Default configuration for the HTTP user-agent header to use in all REST clients.

Can be overwritten by client-specific settings.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_USER_AGENT

Show more

string

The HTTP headers that should be applied to all requests of the rest client.

Environment variable: QUARKUS_REST_CLIENT_HEADERS__HEADER_NAME_

Show more

Map<String,String>

The class name of the host name verifier. The class must have a public no-argument constructor.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_HOSTNAME_VERIFIER

Show more

string

The time in ms for which a connection remains unused in the connection pool before being evicted and closed.

Although this is set in milliseconds, the underlying client can only be configured in seconds, meaning that for this value to actually take effect, it must be higher than 1000; any value less than or equal to 999 is converted to 0 seconds.

A timeout of 0 means there is no timeout.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_CONNECTION_TTL

Show more

int

60000

The size of the connection pool for this client.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_CONNECTION_POOL_SIZE

Show more

int

50

If set to false disables the keep alive completely.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_KEEP_ALIVE_ENABLED

Show more

boolean

true

The maximum number of redirection a request can follow.

Can be overwritten by client-specific settings.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_MAX_REDIRECTS

Show more

int

A boolean value used to determine whether the client should follow HTTP redirect responses.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_FOLLOW_REDIRECTS

Show more

boolean

Fully-qualified provider classnames to include in the client. The equivalent of the @RegisterProvider annotation.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_PROVIDERS

Show more

string

An enumerated type string value with possible values of "MULTI_PAIRS" (default), "COMMA_SEPARATED", or "ARRAY_PAIRS" that specifies the format in which multiple values for the same query parameter is used.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_QUERY_PARAM_STYLE

Show more

multi-pairs, comma-separated, array-pairs

Set whether hostname verification is enabled. Default is enabled. This setting should not be disabled in production as it makes the client vulnerable to MITM attacks.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_VERIFY_HOST

Show more

boolean

The trust store location. Can point to either a classpath resource or a file.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_TRUST_STORE

Show more

string

The trust store password.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_TRUST_STORE_PASSWORD

Show more

string

The type of the trust store. Defaults to "JKS".

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_TRUST_STORE_TYPE

Show more

string

The key store location. Can point to either a classpath resource or a file.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_KEY_STORE

Show more

string

The key store password.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_KEY_STORE_PASSWORD

Show more

string

The type of the key store. Defaults to "JKS".

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_KEY_STORE_TYPE

Show more

string

The name of the TLS configuration to use.

If a name is configured, it uses the configuration from quarkus.tls.<name>.* If a name is configured, but no TLS configuration is found with that name then an error will be thrown. The default TLS configuration will be ignored.

If no named TLS configuration is set, then the key-store, trust-store, etc. properties will be used.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_TLS_CONFIGURATION_NAME

Show more

string

If this is true then HTTP/2 will be enabled.

Environment variable: QUARKUS_REST_CLIENT_HTTP2

Show more

boolean

false

Configures the HTTP/2 upgrade maximum length of the aggregated content in bytes.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_HTTP2_UPGRADE_MAX_CONTENT_LENGTH

Show more

MemorySize 

64K

Configures two different things:

  • The max HTTP chunk size, up to Integer.MAX_VALUE bytes.

  • The size of the chunk to be read when an InputStream is being used as an input

Can be overwritten by client-specific settings.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_MAX_CHUNK_SIZE

Show more

MemorySize 

8k

Supports receiving compressed messages using GZIP. When this feature is enabled and a server returns a response that includes the header Content-Encoding: gzip, REST Client will automatically decode the content and proceed with the message handling.

This property is not applicable to the RESTEasy Client.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_ENABLE_COMPRESSION

Show more

boolean

If the Application-Layer Protocol Negotiation is enabled, the client will negotiate which protocol to use over the protocols exposed by the server. By default, it will try to use HTTP/2 first and if it’s not enabled, it will use HTTP/1.1. When the property http2 is enabled, this flag will be automatically enabled.

Environment variable: QUARKUS_REST_CLIENT_ALPN

Show more

boolean

If true, the stacktrace of the invocation of the REST Client method is captured. This stacktrace will be used if the invocation throws an exception

Environment variable: QUARKUS_REST_CLIENT_CAPTURE_STACKTRACE

Show more

boolean

false

Scope of logging for the client.
WARNING: beware of logging sensitive data
The possible values are:

  • request-response - enables logging request and responses, including redirect responses

  • all - enables logging requests and responses and lower-level logging

  • none - no additional logging

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT_LOGGING_SCOPE

Show more

string

How many characters of the body should be logged. Message body can be large and can easily pollute the logs.

By default, set to 100.

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT_LOGGING_BODY_LIMIT

Show more

int

100

Which request and response headers values to mask in logs.

The value of any matching header will be replaced with "<hidden>". The header name itself remains visible. E.g. Authorization=<hidden>

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT_LOGGING_MASKED_HEADERS

Show more

文字列のリスト

Authorization, Cookie

The CDI scope to use for injection. This property can contain either a fully qualified class name of a CDI scope annotation (such as "jakarta.enterprise.context.ApplicationScoped") or its simple name (such as "ApplicationScoped"). By default, this is not set which means the interface is not registered as a bean unless it is annotated with RegisterRestClient. If an interface is not annotated with RegisterRestClient and this property is set, then Quarkus will make the interface a bean of the configured scope.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__SCOPE

Show more

string

If set to true, then Quarkus will ensure that all calls from the REST client go through a local proxy server (that is managed by Quarkus). This can be very useful for capturing network traffic to a service that uses HTTPS.

This property is not applicable to the RESTEasy Client, only the Quarkus REST client (formerly RESTEasy Reactive client).

This property only applicable to dev and test mode.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__ENABLE_LOCAL_PROXY

Show more

boolean

false

This setting is used to select which proxy provider to use if there are multiple ones. It only applies if enable-local-proxy is true.

The algorithm for picking between multiple provider is the following:

  • If only the default is around, use it (its name is default)

  • If there is only one besides the default, use it

  • If there are multiple ones, fail

Environment variable: QUARKUS_REST_CLIENT__CLIENT__LOCAL_PROXY_PROVIDER

Show more

string

If true, the extension will automatically remove the trailing slash in the paths if any. This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__REMOVES_TRAILING_SLASH

Show more

boolean

true

The base URL to use for this service. This property or the uri property is considered required, unless the baseUri attribute is configured in the @RegisterRestClient annotation.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__URL

Show more

string

The base URI to use for this service. This property or the url property is considered required, unless the baseUri attribute is configured in the @RegisterRestClient annotation.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__URI

Show more

string

This property is only meant to be set by advanced configurations to override whatever value was set for the uri or url. The override is done using the REST Client class name configuration syntax.

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT__CLIENT__OVERRIDE_URI

Show more

string

Map where keys are fully-qualified provider classnames to include in the client, and values are their integer priorities. The equivalent of the @RegisterProvider annotation.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__PROVIDERS

Show more

string

Timeout specified in milliseconds to wait to connect to the remote endpoint.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__CONNECT_TIMEOUT

Show more

Timeout specified in milliseconds to wait for a response from the remote endpoint.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__READ_TIMEOUT

Show more

A boolean value used to determine whether the client should follow HTTP redirect responses.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__FOLLOW_REDIRECTS

Show more

boolean

Mode in which the form data are encoded. Possible values are HTML5, RFC1738 and RFC3986. The modes are described in the Netty documentation

By default, Rest Client Reactive uses RFC1738.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__MULTIPART_POST_ENCODER_MODE

Show more

string

The name of the proxy configuration to use; ignored if quarkus.rest-client."client".proxy-address is set.

If not set and quarkus.rest-client.proxy-configuration-name or the default proxy configuration (quarkus.proxy.*) is set, then the first valid of them will get effective. If the proxy configuration name is set, the configuration from quarkus.proxy.<name>.* will be used. If the proxy configuration name is set, but no proxy configuration is found with that name, then an error will be thrown at runtime.

Use the value none to disable using the default configuration defined via quarkus.rest-client.proxy-configuration-name or quarkus.proxy.*.

Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency) does not support this property.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__PROXY_CONFIGURATION_NAME

Show more

string

An enumerated type string value with possible values of "MULTI_PAIRS" (default), "COMMA_SEPARATED", or "ARRAY_PAIRS" that specifies the format in which multiple values for the same query parameter is used.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__QUERY_PARAM_STYLE

Show more

multi-pairs, comma-separated, array-pairs

Set whether hostname verification is enabled. Default is enabled. This setting should not be disabled in production as it makes the client vulnerable to MITM attacks.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__VERIFY_HOST

Show more

boolean

The trust store location. Can point to either a classpath resource or a file.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__TRUST_STORE

Show more

string

The trust store password.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__TRUST_STORE_PASSWORD

Show more

string

The type of the trust store. Defaults to "JKS".

Environment variable: QUARKUS_REST_CLIENT__CLIENT__TRUST_STORE_TYPE

Show more

string

The key store location. Can point to either a classpath resource or a file.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__KEY_STORE

Show more

string

The key store password.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__KEY_STORE_PASSWORD

Show more

string

The type of the key store. Defaults to "JKS".

Environment variable: QUARKUS_REST_CLIENT__CLIENT__KEY_STORE_TYPE

Show more

string

The class name of the host name verifier. The class must have a public no-argument constructor.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__HOSTNAME_VERIFIER

Show more

string

The name of the TLS configuration to use.

If a name is configured, it uses the configuration from quarkus.tls.<name>.* If a name is configured, but no TLS configuration is found with that name then an error will be thrown. The default TLS configuration will be ignored.

If no named TLS configuration is set, then the key-store, trust-store, etc. properties will be used.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__TLS_CONFIGURATION_NAME

Show more

string

The time in ms for which a connection remains unused in the connection pool before being evicted and closed.

Although this is set in milliseconds, the underlying client can only be configured in seconds, meaning that for this value to actually take effect, it must be higher than 1000; any value less than or equal to 999 is converted to 0 seconds.

A timeout of 0 means there is no timeout.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__CONNECTION_TTL

Show more

int

60000

The size of the connection pool for this client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__CONNECTION_POOL_SIZE

Show more

int

50

If set to false disables the keep alive completely.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__KEEP_ALIVE_ENABLED

Show more

boolean

The maximum number of redirection a request can follow.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__MAX_REDIRECTS

Show more

int

The HTTP headers that should be applied to all requests of the rest client.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__HEADERS__HEADER_NAME_

Show more

Map<String,String>

Set to true to share the HTTP client between REST clients. There can be multiple shared clients distinguished by name, when no specific name is set, the name __vertx.DEFAULT is used.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__SHARED

Show more

boolean

Set the HTTP client name, used when the client is shared, otherwise ignored.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__NAME

Show more

string

Configure the HTTP user-agent header to use.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__USER_AGENT

Show more

string

If this is true then HTTP/2 will be enabled.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__HTTP2

Show more

boolean

Configures the HTTP/2 upgrade maximum length of the aggregated content in bytes.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__HTTP2_UPGRADE_MAX_CONTENT_LENGTH

Show more

MemorySize 

64K

Configures two different things:

  • The max HTTP chunk size, up to Integer.MAX_VALUE bytes.

  • The size of the chunk to be read when an InputStream is being read and sent to the server

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__MAX_CHUNK_SIZE

Show more

MemorySize 

8K

Supports receiving compressed messages using GZIP. When this feature is enabled and a server returns a response that includes the header Content-Encoding: gzip, REST Client will automatically decode the content and proceed with the message handling.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__ENABLE_RESPONSE_DECOMPRESSION

Show more

boolean

If the Application-Layer Protocol Negotiation is enabled, the client will negotiate which protocol to use over the protocols exposed by the server. By default, it will try to use HTTP/2 first and if it’s not enabled, it will use HTTP/1.1. When the property http2 is enabled, this flag will be automatically enabled.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__ALPN

Show more

boolean

If true, the stacktrace of the invocation of the REST Client method is captured. This stacktrace will be used if the invocation throws an exception

Environment variable: QUARKUS_REST_CLIENT__CLIENT__CAPTURE_STACKTRACE

Show more

boolean

If set to true, then this REST Client will not the default exception mapper which always throws an exception if HTTP response code >= 400.

This property is only taken into account if the REST Client returns jakarta.ws.rs.core.Response or org.jboss.resteasy.reactive.RestResponse

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__DISABLE_DEFAULT_MAPPER

Show more

boolean

false

Scope of logging for the client.
WARNING: beware of logging sensitive data
The possible values are:

  • request-response - enables logging request and responses, including redirect responses

  • all - enables logging requests and responses and lower-level logging

  • none - no additional logging

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT__CLIENT__LOGGING_SCOPE

Show more

string

How many characters of the body should be logged. Message body can be large and can easily pollute the logs.

By default, set to 100.

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT__CLIENT__LOGGING_BODY_LIMIT

Show more

int

100

Which request and response headers values to mask in logs.

The value of any matching header will be replaced with "<hidden>". The header name itself remains visible. E.g. Authorization=<hidden>

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT__CLIENT__LOGGING_MASKED_HEADERS

Show more

文字列のリスト

Authorization, Cookie

This property is deprecated: use quarkus.rest-client.proxy-configuration-name instead.

A string value in the form of : that specifies the HTTP proxy server hostname (or IP address) and port for requests of clients to use.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_PROXY_ADDRESS

Show more

string

This property is deprecated: use quarkus.rest-client.proxy-configuration-name instead.

Proxy username, equivalent to the http.proxy or https.proxy JVM settings. Honored only if quarkus.rest-client.proxy-address is set.

Can be overwritten by client-specific settings.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_PROXY_USER

Show more

string

This property is deprecated: use quarkus.rest-client.proxy-configuration-name instead.

Proxy password, equivalent to the http.proxyPassword or https.proxyPassword JVM settings. Honored only if quarkus.rest-client.proxy-address is set.

Can be overwritten by client-specific settings.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_PROXY_PASSWORD

Show more

string

This property is deprecated: use quarkus.rest-client.proxy-configuration-name instead.

Hosts to access without proxy, similar to the http.nonProxyHosts or https.nonProxyHosts JVM settings. Please note that unlike the JVM settings, this property is empty by default. Honored only if quarkus.rest-client.proxy-address is set.

Can be overwritten by client-specific settings.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_NON_PROXY_HOSTS

Show more

string

This property is deprecated: use quarkus.rest-client.proxy-configuration-name instead.

Proxy connection timeout. Honored only if quarkus.rest-client.proxy-address is set.

Can be overwritten by client-specific settings.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT_PROXY_CONNECT_TIMEOUT

Show more

Duration 

10s

This property is deprecated.

A timeout in milliseconds that REST clients should wait to connect to the remote endpoint.

Can be overwritten by client-specific settings.

Environment variable: QUARKUS_REST_CLIENT_CONNECT_TIMEOUT

Show more

15000

This property is deprecated: Use quarkus.rest-client.max-chunk-size instead.

The max HTTP chunk size (8096 bytes by default).

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT_MULTIPART_MAX_CHUNK_SIZE

Show more

int

This property is deprecated: Use quarkus.rest-client.max-chunk-size instead.

The max HTTP chunk size (8096 bytes by default).

This property is not applicable to the Quarkus RESTEasy client (provided by the quarkus-resteasy-client dependency).

Environment variable: QUARKUS_REST_CLIENT__CLIENT__MULTIPART_MAX_CHUNK_SIZE

Show more

int

This property is deprecated: use quarkus.rest-client."client".proxy-configuration-name instead.

A string value in the form of : that specifies the HTTP proxy server hostname (or IP address) and port for requests of this client to use.

Use none to disable proxy

Environment variable: QUARKUS_REST_CLIENT__CLIENT__PROXY_ADDRESS

Show more

string

This property is deprecated: use quarkus.rest-client."client".proxy-configuration-name instead.

Proxy username. Honored only if quarkus.rest-client."client".proxy-address is set.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__PROXY_USER

Show more

string

This property is deprecated: use quarkus.rest-client."client".proxy-configuration-name instead.

Proxy password. Honored only if quarkus.rest-client."client".proxy-address is set.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__PROXY_PASSWORD

Show more

string

This property is deprecated: use quarkus.rest-client."client".proxy-configuration-name instead.

Hosts to access without proxy. Honored only if quarkus.rest-client."client".proxy-address is set.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__NON_PROXY_HOSTS

Show more

string

This property is deprecated: use quarkus.rest-client."client".proxy-configuration-name instead.

Proxy connection timeout. Honored only if quarkus.rest-client."client".proxy-address is set.

This property is not applicable to the RESTEasy Client.

Environment variable: QUARKUS_REST_CLIENT__CLIENT__PROXY_CONNECT_TIMEOUT

Show more

Duration 

10s

MemorySizeフォーマットについて

A size configuration option recognizes strings in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?.

If no suffix is given, assume bytes.

関連コンテンツ