4.8. Eclipse MicroProfile REST クライアントの開発
4.8.1. MicroProfile REST クライアントと JAX-RS 構文の比較
MicroProfile REST クライアントは、CORBA、Java Remote Method Invocation(RMI)、JBoss Remoting Project、RESTEasy にも実装される分散オブジェクト通信のバージョンを有効にします。たとえば、リソースについて考えてみましょう。
@Path("resource") public class TestResource { @Path("test") @GET String test() { return "test"; } }
以下の例は、JAX-RS をネイティブで TestResource
クラスにアクセスする方法を示しています。
Client client = ClientBuilder.newClient(); String response = client.target("http://localhost:8081/test").request().get(String.class);
ただし、Microprofile REST クライアントは、以下の例のように test()
メソッドを直接呼び出すことで、より直感的な構文をサポートします。
@Path("resource") public interface TestResourceIntf { @Path("test") @GET public String test(); } TestResourceIntf service = RestClientBuilder.newBuilder() .baseUrl(http://localhost:8081/)) .build(TestResourceIntf.class); String s = service.test();
上記の例では、TestResource
クラスでの呼び出しは、service.test()
の呼び出しにあるように TestResourceIntf
クラスを使用すると大幅に容易になります。
以下の例は、TestResourceIntf
のより詳細なバージョンです。
@Path("resource") public interface TestResourceIntf2 { @Path("test/{path}")mes("text/plain") @Produces("text/html") @POST public String test(@PathParam("path") String path, @QueryParam("query") String query, String entity); }
service.test("p", "q", "e")
メソッドを呼び出すと、以下の例のように HTTP メッセージが表示されます。
POST /resource/test/p/?query=q HTTP/1.1 Accept: text/html Content-Type: text/plain Content-Length: 1 e
4.8.2. MicroProfile REST クライアントでのプロバイダーのプログラムによる登録
MicroProfile REST クライアントを使用して、プロバイダーを登録してクライアント環境を設定できます。以下に例を示します。
TestResourceIntf service = RestClientBuilder.newBuilder() .baseUrl(http://localhost:8081/)) .register(MyClientResponseFilter.class) .register(MyMessageBodyReader.class) .build(TestResourceIntf.class);
4.8.3. MicroProfile REST クライアントでのプロバイダーの宣言的登録
以下の例のように org.eclipse.microprofile.rest.client.annotation.RegisterProvider
アノテーションをターゲットインターフェイスに追加すると、MicroProfile REST クライアントを 使用してプロバイダーを宣言で登録します。
@Path("resource") @RegisterProvider(MyClientResponseFilter.class) @RegisterProvider(MyMessageBodyReader.class) public interface TestResourceIntf2 { @Path("test/{path}") @Consumes("text/plain") @Produces("text/html") @POST public String test(@PathParam("path") String path, @QueryParam("query") String query, String entity); }
MyClientResponseFilter
クラスと MyMessageBodyReader
クラスをアノテーションで宣言すると、RestClientBuilder.register()
メソッドを呼び出す必要がなくなります。
4.8.4. MicroProfile REST クライアントでのヘッダーの宣言型仕様
HTTP リクエストのヘッダーは、以下の方法で指定できます。
- リソースメソッドパラメーターのいずれかにアノテーションを付けます。
-
org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam
アノテーションを宣言で使用。
以下の例では、@HeaderValue
アノテーションを持つリソースメソッドパラメーターのいずれかにアノテーションを付け、ヘッダーの設定を示しています。
@POST @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.TEXT_PLAIN) String contentLang(@HeaderParam(HttpHeaders.CONTENT_LANGUAGE) String contentLanguage, String subject);
以下の例は、org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam
アノテーションを使用してヘッダーを設定する例になります。
@POST @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.TEXT_PLAIN) @ClientHeaderParam(name=HttpHeaders.CONTENT_LANGUAGE, value="{getLanguage}") String contentLang(String subject); default String getLanguage() { return ...; }
4.8.5. MicroProfile REST クライアントでのサーバーでヘッダーの伝搬
org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory
のインスタンスが有効であれば、受信ヘッダーの送信要求に一括転送できます。デフォルトのインスタンス org.eclipse.microprofile.rest.client.ext.DefaultClientHeadersFactoryImpl
は、コンマ区切りの設定プロパティー org.eclipse.microprofile.rest.client.propagateHeaders
に一覧表示される着信ヘッダーで設定されるマップを返します。
ClientHeadersFactory
インターフェイスをインスタンス化するルールは次のとおりです。
-
JAX-RS リクエストのコンテキストで呼び出される
ClientHeadersFactory
インスタンス は、@Context
アノテーションが付けられたフィールドおよびメソッドの挿入をサポートできます。 -
CDI によって管理される
ClientHeadersFactory
インスタンス は、適切な CDI 管理インスタンスを使用する必要があります。@Inject
インジェクションもサポートする必要があります。
org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory
インターフェイスは以下のように定義されます。
public interface ClientHeadersFactory { /** * Updates the HTTP headers to send to the remote service. Note that providers * on the outbound processing chain could further update the headers. * * @param incomingHeaders - the map of headers from the inbound JAX-RS request. This will * be an empty map if the associated client interface is not part of a JAX-RS request. * @param clientOutgoingHeaders - the read-only map of header parameters specified on the * client interface. * @return a map of HTTP headers to merge with the clientOutgoingHeaders to be sent to * the remote service. */ MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders, MultivaluedMap<String, String> clientOutgoingHeaders); }
その他のリソース
4.8.6. MicroProfile REST クライアントの ResponseExceptionMapper
org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper
は、JAX-RS で定義される javax.ws.rs.ext.ExceptionMapper
クラスと逆のクライアント側です。ExceptionMapper.toResponse()
メソッドは、サーバー側の処理中に発生する Exception
クラスを Response
クラスに変換します。ResponseExceptionMapper.toThrowable()
メソッドは、HTTP エラーステータスでクライアント側で受信した Response
クラスを Exception
クラスに変換します。
ResponseExceptionMapper
クラスは、プログラムまたは宣言で登録できます。登録された ResponseExceptionMapper
クラスがない場合、デフォルトの ResponseExceptionMapper
クラスはステータス >= 400
のレスポンスを WebApplicationException
クラスにマップします。
4.8.7. MicroProfile REST クライアントでのコンテキスト依存関係の挿入
MicroProfile REST クライアントでは、@RegisterRestClient
クラスで CDI Bean として管理されるインターフェイスにアノテーションを付ける必要があります。例を以下に示します。
@Path("resource") @RegisterProvider(MyClientResponseFilter.class) public static class TestResourceImpl { @Inject TestDataBase db; @Path("test/{path}") @Consumes("text/plain") @Produces("text/html") @POST public String test(@PathParam("path") String path, @QueryParam("query") String query, String entity) { return db.getByName(query); } } @Path("database") @RegisterRestClient public interface TestDataBase { @Path("") @POST public String getByName(String name); }
ここで、MicroProfile REST クライアント実装は TestDataBase
クラスサービスのクライアントを作成し、TestResourceImpl
クラスによるアクセスを容易にします。ただし、TestDataBase
クラス実装へのパスに関する情報は含まれません。この情報は、オプションの @RegisterProvider
パラメーター baseUri
で指定できます。
@Path("database") @RegisterRestClient(baseUri="https://localhost:8080/webapp") public interface TestDataBase { @Path("") @POST public String getByName(String name); }
これは、https://localhost:8080/webapp で TestDataBase
の実装にアクセスできることを示しています。以下のシステム変数を使用して情報を外部で提供することもできます。
<fully qualified name of TestDataBase>/mp-rest/url=<URL>
たとえば、以下のコマンドは、https://localhost:8080/webapp にある com.bluemonkeydiamond.TestDatabase
クラスの実装にアクセスできることを示しています。
com.bluemonkeydiamond.TestDatabase/mp-rest/url=https://localhost:8080/webapp