第4章 REST サービスの定義
概要
Apache Camel は、REST サービスを定義するために複数のアプローチをサポートします。特に、Apache Camel は REST DSL (Domain Specific Language) を提供します。これは、REST コンポーネントを抽象化でき、OpenAPI とも統合できるシンプルながらも強力な Fluent API です。
4.1. Camel における REST サービスの概要
概要
Apache Camel は、Camel アプリケーションで REST サービスを定義するためのさまざまなアプローチやコンポーネントを提供します。本セクションでは、これらのアプローチとコンポーネントの概要を紹介し、要件に最適な実装と API を判断できるようにします。
REST とは
Representational State Transfer (REST) は、4 つの基本的な HTTP 動詞 (GET
、POST
、PUT
、および DELETE
) のみを使用して、HTTP 通信でデータ送信を中心とする分散アプリケーションのアーキテクチャーです。
REST アーキテクチャーは HTTP を直接活用します。これは、SOAP のような HTTP を単なるトランスポートプロトコルとして扱うプロトコルとは対象的です。重要なポイントは、HTTP プロトコル 自体 が、既にいくつかの規約によって拡張され、分散アプリケーションのフレームワークとして機能するのに適していることです。
REST 呼び出しのサンプル
REST アーキテクチャーは標準の HTTP メソッドを中心に設定されているため、多くの場合、通常のブラウザーを REST クライアントとして使用することができます。たとえば、ホストとポート localhost:9091
で実行されている単純な Hello World の REST サービスを呼び出すには、ブラウザーで以下の URL にアクセスします。
http://localhost:9091/say/hello/Garp
仮に、Hello World REST サービスが、以下のようなレスポンスを返すとします。
Hello Garp
このレスポンスは、ブラウザーのウィンドウに表示されます。通常のブラウザー (または curl
コマンドラインユーティリティー) だけを使用して、REST サービスを呼び出せる気軽さは、REST プロトコルが急速に人気を集めている多くの理由の 1 つです。
REST ラッパーレイヤー
REST ラッパーレイヤーは、REST サービスを定義するための簡潔な構文を提供し、異なる REST 実装の上に重ねることができます。
- REST DSL
REST DSL (
camel-core
の一部) は、REST サービスを定義するためのシンプルなビルダー API を提供するファサードまたはラッパーレイヤーです。REST DSL 自体は REST 実装を提供しているわけではありません。REST DSL は、ベースとなる REST 実装と組み合わせる必要があります。たとえば、以下の Java コードは、REST DSL を使用してシンプルな Hello World の REST サービスを定義する方法を示しています。rest("/say") .get("/hello/{name}").route().transform().simple("Hello ${header.name}");
詳細は、「REST DSL を使用した REST サービスの定義」 を参照してください。
- REST コンポーネント
REST コンポーネント (
camel-core
の一部) は、URI 構文を使用して REST サービスの定義を可能にするラッパーレイヤーです。REST DSL と同様に、REST コンポーネント自体は REST 実装を提供しているわけではありません。ベースとなる REST 実装と組み合わせる必要があります。HTTP コンポーネントを明示的に指定しない場合、REST DSL はクラスパス上の利用可能なコンポーネントをチェックすることで、どの HTTP コンポーネントを使用するかを自動検出します。REST DSL は、HTTP コンポーネントのデフォルト名を探し、最初に見つかったものを使用します。クラスパス上に HTTP コンポーネントがなく、かつ HTTP トランスポートが明示的に設定されていない場合は、デフォルトの HTTP コンポーネントは
camel-http
になります。注記HTTP コンポーネントの自動検出機能が Camel 2.18 で追加されました。Camel 2.17 では利用できません。
以下の Java DSL は、camel-rest コンポーネントを使用して Hello World のサービスを定義する方法を示しています。
from("rest:get:say:/hello/{name}").transform().simple("Hello ${header.name}");
REST 実装
Apache Camel は、以下のコンポーネントを通じて、複数の REST 実装を提供します。
- Spark-Rest コンポーネント
Spark-Rest コンポーネント (
camel-spark-rest
) は、URI 構文を使用して REST サービスの定義を可能にする REST 実装です。Spark フレームワーク自体は Java の API で、Sinatra フレームワーク (Python の API) を大まかにベースにしています。たとえば、以下の Java コードでは、Spark-Rest コンポーネントを使用して Hello World のサービスを定義する方法を示しています。from("spark-rest:get:/say/hello/:name").transform().simple("Hello ${header.name}");
Rest コンポーネントとは対照的に、URI の変数の構文は
{name}
ではなく、:name
であることに注意してください。注記Spark-Rest コンポーネントには Java 8 が必要です。
- Restlet コンポーネント
Restlet コンポーネント (
camel-restlet
の一部) は、原則として、異なるトランスポートプロトコルの上に重ねることができる REST 実装です (ただし、このコンポーネントは HTTP プロトコルに対してのみテストされます)。このコンポーネントは、Java で REST サービスを開発する商用フレームワークである Restlet Framework との統合も提供します。たとえば、以下の Java コードは Restlet コンポーネントを使用して Hello World のサービスを定義する方法を示しています。from("restlet:http://0.0.0.0:9091/say/hello/{name}?restletMethod=get") .transform().simple("Hello ${header.name}");
詳細は、Apache Camel Component Reference Guide の Restlet を参照してください。
- Servlet コンポーネント
Servlet コンポーネント (
camel-servlet
内) は、Java サーブレットを Camel ルートにバインドするコンポーネントです。言い換えれば、Servlet コンポーネントを使用すると、標準の Java サーブレットのように Camel ルートをパッケージ化してデプロイすることができます。したがって、Servlet コンポーネントは、 サーブレットコンテナー内部に Camel ルートをデプロイする必要がある場合 (たとえば、Apache Tomcat HTTP サーバーや JBoss Enterprise Appication Platform コンテナーなど) に Camel ルートをデプロイする場合に特に便利です。ただし、Servlet コンポーネントだけは、REST サービスの定義に便利な REST API を提供しません。そのため、Servlet コンポーネントを使用する最も簡単な方法は、REST DSL と組み合わせることです。これにより、ユーザーフレンドリーな API で REST サービスを定義できます。
詳細は、Apache Camel Component Reference Guide の Servlet を参照してください。
JAX-RS REST 実装
JAX-RS (Java API for RESTful Web Services) は、REST リクエストを Java オブジェクトにバインドするためのフレームワークです。バインドを定義するには、この Java クラスに JAX-RS のアノテーションを記述する必要があります。JAX-RS フレームワークは比較的成熟しており、REST サービスを開発するための洗練されたフレームワークも提供します。しかし、プログラムするのもやや複雑です。
Apache Camel と JAX-RS の統合は、Apache CXF の上に重ねた CXFRS コンポーネントによって実装されます。簡単にいうと、JAX-RS は以下のアノテーションを使用して REST リクエストを Java クラスにバインドします (以下は多くのアノテーションの一部のみとなります)。
- @Path
- コンテキストパスを Java クラスにマッピングしたり、サブパスを特定の Java メソッドにマッピングしたりできるアノテーション。
- @GET、@POST、@PUT、@DELETE
- HTTP メソッドを Java メソッドにマッピングするアノテーション。
- @PathParam
- URI パラメーターを Java メソッド引数にマッピングするか、URI パラメーターをフィールドに注入するアノテーション。
- @QueryParam
- クエリーパラメーターを Java メソッド引数にマッピングするか、クエリーパラメーターをフィールドに注入するアノテーション。
REST リクエストまたは REST レスポンスのボディーは、通常、JAXB (XML) データフォーマットであることが期待されます。しかし、Apache CXF は JSON 形式から JAXB 形式への変換もサポートしているため、JSON メッセージも解析することができます。
詳細は、Apache Camel Component Reference Guide および Apache CXF Development Guide の CXFRS を参照してください。
CXFRS コンポーネントは REST DSL と統合されていません。