RESTURL パスの構成

JPA リポジトリのリソースがエクスポートされる URL パスのセグメントを構成できます。これを行うには、クラスレベルまたはクエリメソッドレベルでアノテーションを追加します。

デフォルトでは、エクスポータはドメインクラスの名前を使用して CrudRepository を公開します。Spring Data REST は、この単語を複数形にするために Evo Inflector [GitHub] (英語) も適用します。次のリポジトリ定義を検討してください。

interface PersonRepository extends CrudRepository<Person, Long> {}

前の例で定義されたリポジトリは、localhost:8080/persons/ で公開されています。

リポジトリのエクスポート方法を変更するには、次の例に示すように、クラスレベルで @RestResource アノテーションを追加します。

@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {}

前の例で定義されたリポジトリには、localhost:8080/people/ からアクセスできます。

次の例に示すように、クエリメソッドを定義している場合、それらもデフォルトで名前で公開されます。

interface PersonRepository extends CrudRepository<Person, Long> {

  List<Person> findByName(String name);
}

前の例のメソッドは、localhost:8080/persons/search/findByName で公開されています。

すべてのクエリメソッドリソースは、search リソースで公開されます。

このクエリメソッドが公開されている URL のセグメントを変更するには、次の例に示すように、@RestResource アノテーションを再度使用できます。

@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(path = "names")
  List<Person> findByName(String name);
}

これで、前の例のクエリメソッドが localhost:8080/people/search/names で公開されました。

rel 属性の処理

これらのリソースはすべて検出可能であるため、エクスポーターによって送信されるリンクでの rel 属性の表示方法にも影響を与える可能性があります。

たとえば、デフォルトの構成では、localhost:8080/persons/search にリクエストを発行して、公開されているクエリメソッドを確認すると、次のようなリンクのリストが返されます。

{
  "_links" : {
    "findByName" : {
      "href" : "http://localhost:8080/persons/search/findByName"
    }
  }
}

rel 値を変更するには、次の例に示すように、@RestResource アノテーションの rel プロパティを使用します。

@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(path = "names", rel = "names")
  List<Person> findByName(String name);
}

上記の例では、次のリンク値が生成されます。

{
  "_links" : {
    "names" : {
      "href" : "http://localhost:8080/persons/search/names"
    }
  }
}
これらの JSON のスニペットは、Spring Data REST のデフォルト形式の HAL (英語) を使用することを前提としています。HAL をオフにすると、出力が異なって見える可能性があります。ただし、rel 名をオーバーライドする機能は、レンダリング形式から完全に独立しています。

次の例に示すように、リポジトリの rel を変更できます。

@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(path = "names", rel = "names")
  List<Person> findByName(String name);
}

次の出力例に示すように、リポジトリの rel を変更すると、最上位の名前が変更されます。

{
  "_links" : {
    "people" : {
      "href" : "http://localhost:8080/people"
    },
    …
  }
}

前の出力に示されている最上位のフラグメント:

  • path = "people" は、href の値を /persons から /people に変更しました。

  • rel = "people" は、そのリンクの名前を persons から people に変更しました。

このリポジトリの search リソースに移動すると、ファインダーメソッドの @RestResource アノテーションによってパスが次のように変更されます。

{
  "_links" : {
    "names" : {
      "href" : "http://localhost:8080/people/search/names"
    }
  }
}

リポジトリ定義内のこのアノテーションのコレクションにより、次の変更が発生しました。

  • リポジトリレベルのアノテーションの path = "people" は、/people とともにベース URI に反映されます。

  • ファインダーメソッドを含めると、/people/search が提供されます。

  • path = "names" は /people/search/names の URI を作成します。

  • rel = "names" は、そのリンクの名前を findByNames から names に変更します。

特定のリポジトリ、クエリメソッド、フィールドを非表示にする

特定のリポジトリ、リポジトリのクエリメソッド、エンティティのフィールドをまったくエクスポートしたくない場合があります。例としては、User オブジェクトの password などのフィールドや同様の機密データを非表示にすることが含まれます。これらのアイテムをエクスポートしないようにエクスポーターに指示するには、@RestResource でアノテーションを付け、exported = false を設定します。

例: リポジトリのエクスポートをスキップするには、次の例のようなリポジトリ定義を作成できます。

@RepositoryRestResource(exported = false)
interface PersonRepository extends CrudRepository<Person, Long> {}

クエリメソッドのエクスポートをスキップするには、次のように、クエリメソッドに @RestResource(exported = false) アノテーションを付けることができます。

@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(exported = false)
  List<Person> findByName(String name);
}

同様に、フィールドのエクスポートをスキップするには、次のように、フィールドに @RestResource(exported = false) でアノテーションを付けることができます。

@Entity
public class Person {

  @Id @GeneratedValue private Long id;

  @OneToMany
  @RestResource(exported = false)
  private Map<String, Profile> profiles;
}
射影は、エクスポートされるものを変更し、これらの設定を効果的に回避する手段を提供します。同じドメインオブジェクトに対して射影を作成する場合は、フィールドをエクスポートしないでください。

リポジトリの CRUD メソッドを非表示にする

CrudRepository で保存または削除メソッドを公開したくない場合は、オフにするメソッドをオーバーライドし、オーバーライドされたバージョンにアノテーションを配置することで、@RestResource(exported = false) 設定を使用できます。例: HTTP ユーザーが CrudRepository の削除メソッドを呼び出さないようにするには、次のように、それらすべてをオーバーライドし、オーバーライドされたメソッドにアノテーションを追加します。

@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @Override
  @RestResource(exported = false)
  void delete(Long id);

  @Override
  @RestResource(exported = false)
  void delete(Person entity);
}
両方の delete メソッドをオーバーライドすることが重要です。ランタイムパフォーマンスを高速化するために、エクスポーターは現在、使用する CRUD メソッドを決定するためにやや単純なアルゴリズムを使用しています。現在、ID を取得する delete のバージョンをオフにすることはできませんが、エンティティインスタンスを取得するバージョンをエクスポートすることはできません。当面は、delete メソッドをエクスポートするかどうかを選択できます。オフにしたい場合は、両方のバージョンに exported = false のアノテーションを付ける必要があることに注意してください。