Menu Close

46.5. サブリソースの使用

概要

サービスは、複数のリソースで処理する必要がある可能性があります。たとえば、注文処理サービスのベストプラクティスでは、各顧客が一意のリソースとして処理されることが推奨されています。各注文も一意のリソースとして処理されます。

JAX-RS API を使用して、顧客リソースと注文リソースをサブリソースとして実装します。サブリソースは、ルートリソースクラス経由でアクセスされるリソースです。これらは、@Path アノテーションをリソースクラスのメソッドに追加して定義されます。サブリソースは、以下の 2 つの方法の 1 つで実装できます。

サブリソースの指定

サブリソースを指定するには、@Path アノテーションをメソッドに付けます。サブリソースの URI は以下のように構築されます。

  1. サブリソースの @Path アノテーションの値を、サブリソースの親リソースの @Path アノテーションの値に追加します。

    親リソースの @Path アノテーションは、サブリソースを含むクラスのオブジェクトを返すリソースクラスのメソッドにある場合があります。

  2. ルートリソースに達するまで前述の手順を繰り返します。
  3. アセンブルされた 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}/ に一致するリソースの HTTP GET リクエストを処理します。
  • updateOrder()は、URI が /customerservice/orders/{orderId}/ に一致するリソースの HTTP PUT リクエストを処理します。
  • newOrder() は、/customerservice/orders/ でリソースの HTTP POST 要求を処理します。

例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 テンプレートを持つサブリソースメソッドは、サブリソースロケーターによって返されるリソースクラスと同等です。

サブリソースロケーター

サブリソースロケーターは、HTTP 動詞アノテーションのいずれか付いておらず、サブリソースのリクエストを直接処理しません。代わりに、サブリソースロケーターは要求を処理できるリソースクラスのインスタンスを返します。

HTTP 動詞アノテーションがない他に、サブリソースロケーターにはエンティティーパラメーターもありません。サブリソースロケーターメソッドによって使用されるすべてのパラメーターは、47章リソースクラスとメソッドに情報を渡す に記載されているアノテーションのいずれかを使用する必要があります。

例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 クラスを拡張した ppOrderccOder の 2 つのクラスを実装することのみが必要になります。processOrder() の実装は、必要なロジックを基づいて、サブリソースの必要な実装をインスタンス化します。