Configuring the REST URL Path

你可以配置 JPA 储存库的资源导出的 URL 路径的段。要做到这一点,请在类级别或查询方法级别添加一个注解。 默认情况下,导出程序使用域类的名称展示您的 CrudRepository。Spring Data REST 也应用 Evo Inflector来复数化此字。请考虑以下资源库定义:

interface PersonRepository extends CrudRepository<Person, Long> {}

前面示例中定义的储存库公开在 http://localhost:8080/persons/。 若要更改储存库的导出方式,请在类级别添加一个 @RestResource 注解,如下例所示:

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

前面示例中定义的储存库可访问 http://localhost:8080/people/。 如果你定义了查询方法,它们也会默认按其名称公开,如下例所示:

interface PersonRepository extends CrudRepository<Person, Long> {

  List<Person> findByName(String name);
}

前面示例中的方法公开在 http://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);
}

现在,前面示例中的查询方法公开在 http://localhost:8080/people/search/names

Handling rel Attributes

由于这些资源都是可被发现的,你还可以影响导出器发送的链接中 rel 属性的显示方式。

例如,在默认配置中,如果你向 http://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

Hiding Certain Repositories, Query Methods, or Fields

您可能不希望导出某个存储库、存储库上的查询方法或实体的字段。例如,隐藏 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;
}

投影提供了更改导出内容及其 side-step these settings 的方式。如果你对同一个域对象创建任何投影,请务必不要导出字段。

Hiding Repository CRUD Methods

如果您不希望在 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);
}

重要的是,你覆盖 both delete 方法。在运行时性能更快的目标下,导出器当前使用一个有点幼稚的算法来确定使用哪个 CRUD 方法。你目前无法关闭具有 ID 的 delete 版本,而是导出具有实体实例的版本。在此期间,你可以导出 delete 方法或不导出。如果你想关闭它们,请记住你必须使用 exported = false 对这两个版本进行注释。