Configuring the REST URL Path

你可以配置 JPA 储存库的资源导出的 URL 路径的段。要做到这一点,请在类级别或查询方法级别添加一个注解。

You can configure the segments of the URL path under which the resources of a JPA repository are exported. To do so, add an annotation at the class level or at the query method level.

默认情况下,导出程序使用域类的名称展示您的 CrudRepository。Spring Data REST 也应用 Evo Inflector来复数化此字。请考虑以下资源库定义:

By default, the exporter exposes your CrudRepository by using the name of the domain class. Spring Data REST also applies the Evo Inflector to pluralize this word. Consider the following repository definition:

interface PersonRepository extends CrudRepository<Person, Long> {}

前面示例中定义的储存库公开在 http://localhost:8080/persons/

The repository defined by the preceding example is exposed at http://localhost:8080/persons/.

若要更改储存库的导出方式,请在类级别添加一个 @RestResource 注解,如下例所示:

To change how the repository is exported, add a @RestResource annotation at the class level, as the following example shows:

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

前面示例中定义的储存库可访问 http://localhost:8080/people/

The repository defined by the preceding example is accessible at http://localhost:8080/people/.

如果你定义了查询方法,它们也会默认按其名称公开,如下例所示:

If you have query methods defined, those also default to being exposed by their name, as the following example shows:

interface PersonRepository extends CrudRepository<Person, Long> {

  List<Person> findByName(String name);
}

前面示例中的方法公开在 http://localhost:8080/persons/search/findByName

The method in the preceding example is exposed at http://localhost:8080/persons/search/findByName.

所有查询方法资源均在 search 资源下公开。

All query method resources are exposed under the search resource.

若要更改此查询方法公开的 URL 段,你可以再次使用 @RestResource 注解,如下例所示:

To change the segment of the URL under which this query method is exposed, you can use the @RestResource annotation again, as the following example shows:

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

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

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

Now the query method in the preceding example is exposed at http://localhost:8080/people/search/names.

Handling rel Attributes

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

Since these resources are all discoverable, you can also affect how the rel attribute is displayed in the links sent out by the exporter.

例如,在默认配置中,如果你向 http://localhost:8080/persons/search 发出请求以找出公开了哪些查询方法,你将得到一个类似于以下内容的链接列表:

For instance, in the default configuration, if you issue a request to http://localhost:8080/persons/search to find out what query methods are exposed, you get back a list of links similar to the following:

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

若要更改 rel 值,请使用 @RestResource 注释中的 rel 属性,如下例所示:

To change the rel value, use the rel property on the @RestResource annotation, as the following example shows:

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

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

上述示例生成以下链接值:

The preceding example results in the following link value:

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

JSON 代码片段假设你使用了 Spring Data REST 的 HAL 默认格式。你可以关闭 HAL, 这将导致输出看起来不同。然而,你覆盖 rel 名称的能力完全独立于渲染格式。

These snippets of JSON assume you use Spring Data REST’s default format of HAL. You can turn off HAL, which would cause the output to look different. However, your ability to override rel names is totally independent of the rendering format.

您可以更改存储库的 rel,如下例所示:

You can change the rel of a repository, as the following example shows:

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

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

更改存储库的 rel 会更改顶级名称,如下例输出所示:

Altering the rel of a repository changes the top-level name, as the following example output shows:

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

在上述输出中显示的顶级片段中:

In the top level fragment shown in the preceding output:

  • path = "people" changed the value in href from /persons to /people.

  • rel = "people" changed the name of that link from persons to people.

当您导航到此存储库的 search 资源时,查找器方法的 @RestResource 注释已更改路径,如下所示:

When you navigate to the search resource of this repository, the finder method’s @RestResource annotation has altered the path, as follows:

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

存储库定义中的此注释集合导致下列更改:

This collection of annotations in your repository definition has caused the following changes:

  • The Repository-level annotation’s path = "people" is reflected in the base URI with /people.

  • The inclusion of a finder method provides you with /people/search.

  • path = "names" creates a URI of /people/search/names.

  • rel = "names" changes the name of that link from findByNames to names.

Hiding Certain Repositories, Query Methods, or Fields

您可能不希望导出某个存储库、存储库上的查询方法或实体的字段。例如,隐藏 User 对象上的 password 之类字段和类似敏感数据。若要告诉导出程序不要导出这些项目,请使用 @RestResource 对它们进行注释,并设置 exported = false

You may not want a certain repository, a query method on a repository, or a field of your entity to be exported at all. Examples include hiding fields like password on a User object and similar sensitive data. To tell the exporter to not export these items, annotate them with @RestResource and set exported = false.

例如,若要跳过导出存储库,您可以创建类似于以下示例的存储库定义:

For example, to skip exporting a repository, you could create a repository definition similar to the following example:

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

若要跳过导出查询方法,您可以使用 @RestResource(exported = false) 注释查询方法,如下所示:

To skip exporting a query method, you can annotate the query method with @RestResource(exported = false), as follows:

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

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

类似地,若要跳过导出字段,您可以使用 @RestResource(exported = false) 注释字段,如下所示:

Similarly, to skip exporting a field, you can annotate the field with @RestResource(exported = false), as follows:

@Entity
public class Person {

  @Id @GeneratedValue private Long id;

  @OneToMany
  @RestResource(exported = false)
  private Map<String, Profile> profiles;
}

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

Projections provide the means to change what is exported and effectively projections-excerpts.hidden-data. If you create any projections against the same domain object, be sure to NOT export the fields.

Hiding Repository CRUD Methods

如果您不希望在 CrudRepository 上公开保存或删除方法,可以使用 @RestResource(exported = false) 设置覆盖要关闭的方法并将注释放在被覆盖版本上。例如,为了防止 HTTP 用户调用 CrudRepository 的删除方法,请覆盖全部方法并在被覆盖方法上添加注释,如下所示:

If you do not want to expose a save or delete method on your CrudRepository, you can use the @RestResource(exported = false) setting by overriding the method you want to turn off and placing the annotation on the overridden version. For example, to prevent HTTP users from invoking the delete methods of CrudRepository, override all of them and add the annotation to the overridden methods, as follows:

@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 对这两个版本进行注释。

It is important that you override both delete methods. In the interest of faster runtime performance, the exporter currently uses a somewhat naive algorithm for determining which CRUD method to use. You cannot currently turn off the version of delete that takes an ID but export the version that takes an entity instance. For the time being, you can either export the delete methods or not. If you want turn them off, keep in mind that you have to annotate both versions with exported = false.