RESTEasyクライアントAPI

RESTEasyクライアントAPI

1. 前書き

previous articleでは、JAX-RS 2.0RESTEasyサーバー側実装に焦点を当てました。

JAX-RS 2.0は新しいクライアントAPIを導入し、リモートのRESTfulWebサービスにHTTPリクエストを送信できるようにします。 Jersey、Apache CXF、Restlet、およびRESTEasyは、最も一般的な実装のサブセットにすぎません。

この記事では、RESTEasy APIを使用してリクエストを送信することにより、REST APIを消費する方法について説明します。

2. プロジェクトのセットアップ

pom.xmlに次の依存関係を追加します。


    3.0.14.Final


    
        org.jboss.resteasy
        resteasy-client
        ${resteasy.version}
    
    ...

3. クライアントサイドコード

クライアントの実装は非常に大きく、3つの主要なクラスで構成されています。

    • クライアント

    • WebTarget

    • 応答

Clientインターフェースは、WebTargetインスタンスのビルダーです。

WebTargetは、より多くのサブリソースWebTargetを構築したり、要求を呼び出したりできる、個別のURLまたはURLテンプレートを表します。

クライアントを作成するには、実際に2つの方法があります。

  • org.jboss.resteasy.client.ClientRequestを使用する標準的な方法

  • RESTeasy Proxy FrameworkResteasyClientBuilderクラスを使用する

ここではRESTEasyプロキシフレームワークに焦点を当てます。

JAX-RSアノテーションを使用して着信要求をRESTFul Webサービスメソッドにマッピングする代わりに、クライアントフレームワークは、リモートRESTful Webサービスで呼び出すために使用するHTTP要求を構築します。

それでは、Javaインターフェースの作成を開始し、メソッドとインターフェースでJAX-RSアノテーションを使用してみましょう。

3.1. ServicesClientインターフェース

@Path("/movies")
public interface ServicesInterface {

    @GET
    @Path("/getinfo")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    Movie movieByImdbId(@QueryParam("imdbId") String imdbId);

    @POST
    @Path("/addmovie")
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    Response addMovie(Movie movie);

    @PUT
    @Path("/updatemovie")
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    Response updateMovie(Movie movie);

    @DELETE
    @Path("/deletemovie")
    Response deleteMovie(@QueryParam("imdbId") String imdbId);
}

3.2. 映画教室

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "movie", propOrder = { "imdbId", "title" })
public class Movie {

    protected String imdbId;
    protected String title;

    // getters and setters
}

3.3. リクエストの作成

次に、APIを使用するために使用できるプロキシクライアントを生成します。

String transformerImdbId = "tt0418279";
Movie transformerMovie = new Movie("tt0418279", "Transformer 2");
final String path = "http://127.0.0.1:8080/RestEasyTutorial/rest";

ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target(UriBuilder.fromPath(path));
ServicesInterface proxy = target.proxy(ServicesInterface.class);

// POST
Response moviesResponse = proxy.addMovie(transformerMovie);
System.out.println("HTTP code: " + moviesResponse.getStatus());
moviesResponse.close();

// GET
Movie movies = proxy.movieByImdbId(transformerImdbId);

// PUT
transformerMovie.setTitle("Transformer 4");
moviesResponse = proxy.updateMovie(transformerMovie);
moviesResponse.close();

// DELETE
moviesResponse = proxy.deleteMovie(batmanMovie.getImdbId());
moviesResponse.close();

RESTEasyクライアントAPIはApacheHttpClientに基づいていることに注意してください。

また、各操作の後、新しい操作を実行する前に応答を閉じる必要があることにも注意してください。 これが必要なのは、デフォルトでは、クライアントが使用できるHTTP接続が1つしかないためです。

最後に、DTOを直接操作する方法に注意してください。JSONまたはXMLとの間のマーシャル/アンマーシャルロジックは扱っていません。これは、Movieクラスに適切な注釈が付けられているため、JAXBまたはJacksonを使用して舞台裏で発生します.

3.4. 接続プールを使用したリクエストの作成

前の例の1つの注意点は、使用可能な接続が1つしかないことです。 たとえば–の場合、次のことを試みます。

Response batmanResponse = proxy.addMovie(batmanMovie);
Response transformerResponse = proxy.addMovie(transformerMovie);

batmanResponseclose()を呼び出さない場合–2行目が実行されると例外がスローされます。

java.lang.IllegalStateException:
Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.

繰り返しますが、これは、RESTEasyが使用するデフォルトのHttpClientorg.apache.http.impl.conn.SingleClientConnManagerであるために発生します。もちろん、これにより、単一の接続のみが使用可能になります。

ここで、その制限を回避するには、RestEasyClientインスタンスを別の方法で作成する必要があります(接続プールを使用)。

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
cm.setMaxTotal(200); // Increase max total connection to 200
cm.setDefaultMaxPerRoute(20); // Increase default max connection per route to 20
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);

ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
ResteasyWebTarget target = client.target(UriBuilder.fromPath(path));
ServicesInterface proxy = target.proxy(ServicesInterface.class);

これで、benefit from a proper connection poolを実行でき、毎回接続を解放する必要なしに、クライアントを介して複数の要求を実行できます。

4. 結論

このクイックチュートリアルでは、RESTEasy Proxy Frameworkを紹介し、それを使用して非常にシンプルなクライアントAPIを構築しました。

このフレームワークは、クライアントを構成するためのヘルパーメソッドをいくつか提供し、JAX-RSサーバー側の仕様とは反対のミラーとして定義できます。

この記事で使用されている例は、sample project in GitHubとして利用できます。