46.5. サブリソースの操作
概要
サービスは複数のリソースで処理する必要がある場合が多いです。たとえば、注文処理サービスのベストプラクティスでは、各顧客を一意のリソースとして処理することを提案しています。各注文は、一意のリソースとしても処理されます。
JAX-RS API を使用して、顧客リソースと注文リソースを サブ リソースとして実装します。サブリソースは、ルートリソースクラスを介してアクセスされるリソースです。これらは、@Path
アノテーションをリソースクラスのメソッドに追加して定義されます。サブリソースは、次の 2 つの方法のいずれかで実装できます。
- サブリソースメソッド: サブリソースの HTTP 動詞を直接実装し、「HTTP 動詞の指定」 で説明されているアノテーションの 1 つを付けます。
- サブリソースロケーター: サブリソースを実装するクラスを指します。
サブリソースの指定
サブリソースを指定するには、@Path
アノテーションをメソッドに付けます。サブリソースの URI は次のように設定されます。
サブリソースの
@Path
アノテーションの値を、サブリソースの親リソースの@Path
アノテーションの値に追加します。親リソースの
@Path
アノテーションは、サブリソースを含むクラスのオブジェクトを返すリソースクラスのメソッドにある場合があります。- ルートリソースに到達するまで、前の手順を繰り返します。
- 組み立てられ URI は、サービスがデプロイされるベース URI に追加されます。
たとえば、例46.6「サブリソースの注文」 に示されているサブリソースの URI は、baseURI/customerservice/order/12 である可能性があります。
例46.6 サブリソースの注文
... @Path("/customerservice/") public class CustomerService { ... @Path("/orders/{orderId}/") @GET public Order getOrder(@PathParam("orderId") String orderId) { ... } }
サブリソースメソッド
サブリソースメソッドには、@Path
アノテーションと HTTP 動詞アノテーションのいずれが付けられます。れます。サブリソースメソッドは、指定された HTTP 動詞を使用してリソースに対して行われた要求の処理を直接担当します。
例46.7「サブリソースメソッド」 は、3 つのサブリソースメソッドを持つリソースクラスを示しています。
-
getOrder()
は、URI が /customerservice/orders/{orderId}/ に一致するリソースの HTTPGET
リクエストを処理します。 -
updateOrder()
は、URI が /customerservice/orders/{orderId}/ に一致するリソースの HTTPPUT
リクエストを処理します。 -
newOrder()
は、/customerservice/orders/ でリソースの HTTPPOST
要求を処理します。
例46.7 サブリソースメソッド
... @Path("/customerservice/") public class CustomerService { ... @Path("/orders/{orderId}/") @GET public Order getOrder(@PathParam("orderId") String orderId) { ... } @Path("/orders/{orderId}/") @PUT public Order updateOrder(@PathParam("orderId") String orderId, Order order) { ... } @Path("/orders/") @POST public Order newOrder(Order order) { ... } }
URI テンプレートが同じサブリソースメソッドは、サブリソースロケーターによって返されるリソースクラスと同じです。
sub-resource ロケーター
サブリソースロケーターは、HTTP 動詞アノテーションの 1 つが追加されておらず、サブリソースでの要求は直接処理されません。代わりに、サブリソースロケーターは、要求を処理できるリソースクラスのインスタンスを返します。
HTTP 動詞アノテーションがないことに加えて、サブリソースロケーターはエンティティーパラメーター指定できません。サブリソースロケーターメソッドで使用されるすべてのパラメーターは、47章リソースクラスとメソッドへの情報の受け渡し で説明されているアノテーションの 1 つを使用する必要があります。
例46.8「特定のクラスを返すサブリソースロケーター」 に示すように、サブリソースロケーターを使用すると、すべてのメソッドを 1 つのスーパークラスに配置する代わりに、リソースを再利用可能なクラスとしてカプセル化できます。processOrder()
メソッドはサブリソースロケーターです。URI テンプレート /orders/{orderId}/ に一致する URI でリクエストが実行されると、Order
クラスのインスタンスが返されます。Order
クラスには、HTTP 動詞アノテーションが付いたメソッドがあります。PUT
リクエストは updateOrder()
メソッドによって処理されます。
例46.8 特定のクラスを返すサブリソースロケーター
... @Path("/customerservice/") public class CustomerService { ... @Path("/orders/{orderId}/") public Order processOrder(@PathParam("orderId") String orderId) { ... } ... } public class Order { ... @GET public Order getOrder(@PathParam("orderId") String orderId) { ... } @PUT public Order updateOrder(@PathParam("orderId") String orderId, Order order) { ... } }
ポリモーフィズムをサポートできるように、サブリソースロケーターは実行時に処理されます。サブリソースロケーターの戻り値は、汎用 Object
、抽象クラス、またはクラス階層の最上位になります。たとえば、サービスで PayPal の注文とクレジットカードの注文の両方を処理する必要がある場合、例46.8「特定のクラスを返すサブリソースロケーター」からの processOrder()
メソッドの署名は変更されません。Order
クラスを拡張した ppOrder
と ccOder
の 2 つのクラスを実装することのみが必要になります。processOrder()
の実装は、必要なロジックを基づいて、サブリソースの必要な実装をインスタンス化します。