配置 REST URL 路徑

您可以配置 JPA 儲存庫資源匯出的 URL 路徑區段。若要執行此操作,請在類別層級或查詢方法層級新增註解。

預設情況下,匯出器會使用網域類別的名稱來公開您的 CrudRepository。Spring Data REST 也會套用 Evo Inflector 來將此單字變為複數。請考慮以下儲存庫定義

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" : "https://127.0.0.1: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" : "https://127.0.0.1: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" : "https://127.0.0.1:8080/people"
    },
    …
  }
}

在上述輸出中顯示的最上層片段中

  • path = "people" 將 href 中的值從 /persons 變更為 /people

  • rel = "people" 將該連結的名稱從 persons 變更為 people

當您導覽至此儲存庫的 search 資源時,finder 方法的 @RestResource 註解已變更路徑,如下所示

{
  "_links" : {
    "names" : {
      "href" : "https://127.0.0.1:8080/people/search/names"
    }
  }
}

您儲存庫定義中的此註解集合已造成以下變更

  • 儲存庫層級註解的 path = "people" 反映在基本 URI 中,為 /people

  • 包含 finder 方法為您提供 /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 上的 savedelete 方法,您可以藉由覆寫您要關閉的方法並將註解放在覆寫版本上,來使用 @RestResource(exported = false) 設定。例如,若要防止 HTTP 使用者叫用 CrudRepositorydelete 方法,請覆寫所有方法並將註解新增至覆寫的方法,如下所示

@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 註解兩個版本。