1. Introduction
1.绪论
Spring Data REST can remove a lot of boilerplate that’s natural to REST services.
Spring Data REST可以去除很多REST服务中自然存在的模板。
In this tutorial, we’ll explore how to customize some of Spring Data REST’s HTTP binding defaults.
在本教程中,我们将探讨如何自定义Spring Data REST的一些HTTP绑定默认值。
2. Spring Data REST Repository Fundamentals
2.Spring Data REST Repository基础知识
To get started, let’s create an empty interface that extends the CrudRepository interface, specifying the type of our entity and the type of its primary key:
为了开始,让我们创建一个扩展CrudRepository接口的空接口,指定我们实体的类型和主键的类型。
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}
By default, Spring generates all the mappings needed, configures each resource to be accessible via the appropriate HTTP methods, and returns the proper status codes.
默认情况下,Spring会生成所有需要的映射,将每个资源配置为可通过适当的HTTP方法访问,并返回适当的状态代码。
If we don’t need all the resources defined in CrudRepository, we can extend the basic Repository interface and define only the resources we want:
如果我们不需要CrudRepository中定义的所有资源,我们可以扩展基本的Repository接口,只定义我们想要的资源。
public interface UserRepository extends Repository<WebsiteUser, Long> {
void deleteById(Long aLong);
}
Upon receiving a request, Spring reads the HTTP Method used and, depending on the resource type, calls the appropriate method defined in our interface, if present, or returns an HTTP status 405 (Method Not Allowed) otherwise.
收到请求后,Spring会读取所使用的HTTP方法,并根据资源类型,调用我们接口中定义的适当方法(如果存在),否则返回HTTP状态 405(方法不允许)。
With reference to the code above, when Spring receives a DELETE request, it executes our deleteById method.
参照上面的代码,当Spring收到一个DELETE请求时,它会执行我们的deleteById方法。
3. Restricting Which HTTP Methods Are Exposed
3.限制哪些HTTP方法被暴露
Let’s imagine we have a user management system. We might, then, have a UserRepository.
让我们想象一下,我们有一个用户管理系统。那么,我们可能有一个UserRepository.。
And, since we are using Spring Data REST, we get a lot from having it extend CrudRepository:
而且,由于我们使用的是Spring Data REST,我们从让它扩展CrudRepository中得到很多。
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}
All our resources are exposed using the default CRUD pattern, so issuing the following command:
我们所有的资源都是使用默认的CRUD模式暴露的,所以发出以下命令。
curl -v -X DELETE http://localhost:8080/users/<existing_user_id>
will return an HTTP status 204 (No Content returned) to confirm the deletion.
将返回一个HTTP状态204(无内容返回)以确认删除。
Now, let’s assume we want to hide the delete method from third parties while being able to use it internally.
现在,让我们假设我们想从第三方隐藏delete方法,同时能够在内部使用它。
We can then first add the deleteById method signature into our interface, which signals to Spring Data REST that we are going to configure it.
然后,我们可以首先将deleteById方法签名添加到我们的接口中,这就向Spring Data REST发出信号,表明我们要对其进行配置。
Then, we can use the annotation @RestResource(exported = false), which will configure Spring to skip this method when triggering the HTTP method exposure:
然后,我们可以使用注解@RestResource(exported = false),这将配置Spring在触发HTTP方法暴露时跳过这个方法。
@Override
@RestResource(exported = false)
void deleteById(Long aLong);
Now, if we repeat the same cUrl command shown above, we’ll receive an HTTP Status 405 (Method Not Allowed) instead.
现在,如果我们重复上面的cUrl命令,我们将收到一个HTTP状态405(方法不允许)。
4. Customizing Supported HTTP Methods
4.定制支持的HTTP方法
The @RestResource annotation also gives us the ability to customize the URL path mapped to a repository method and the link id in the JSON returned by the HATEOAS resource discovery.
@RestResource注解还使我们能够自定义映射到资源库方法的URL路径以及HATEOAS资源发现所返回的JSON中的链接ID。
To do that, we use the optional parameters of the annotation:
要做到这一点,我们使用注释的可选参数。
- path for the URL path
- rel for the link id
Let’s go back to our UserRepository and add a simple findByEmail method:
让我们回到我们的UserRepository,添加一个简单的findByEmail方法。
WebsiteUser findByEmail(@Param("email") String email);
By executing a cUrl to http://localhost:8080/users/search/, we can now see our new method listed with other resources:
通过执行cUrl到http://localhost:8080/users/search/,我们现在可以看到我们的新方法与其他资源一起列出。
{
"_links": {
"findByEmail": {
"href": "http://localhost:8080/users/search/findByEmail{?email}"
},
"self": {
"href": "http://localhost:8080/users/search/"
}
}
}
If we don’t like the default path, instead of changing the repository method, we can simply add the @RestResource annotation:
如果我们不喜欢默认的路径,我们可以简单地添加@RestResource注解,而不是改变存储库方法。
@RestResource(path = "byEmail", rel = "customFindMethod")
WebsiteUser findByEmail(@Param("email") String email);
And if we do the resource discovery again, the resulting JSON will confirm our changes:
如果我们再次进行资源发现,所产生的JSON将确认我们的变化。
{
"_links": {
"customFindMethod": {
"href": "http://localhost:8080/users/search/byEmail{?email}",
"templated": true
},
"self": {
"href": "http://localhost:8080/users/search/"
}
}
}
5. Programmatic Configuration
5.程序化配置
Sometimes we need a finer-grained level of configuration to expose or restrict access to our HTTP methods. For example, POST on collection resources, as well as PUT and PATCH on item resources, all use the same save method.
有时我们需要更细粒度的配置来公开或限制对我们的HTTP方法的访问。例如,集合资源上的POST,以及项目资源上的PUT和PATCH,都使用相同的save方法。
Starting from Spring Data REST 3.1, and available with Spring Boot 2.1, we can change the exposure of a specific HTTP method through the ExposureConfiguration class. This particular configuration class exposes a lambda-based API to define both global and type-based rules.
从Spring Data REST 3.1开始,并在Spring Boot 2.1中可用,我们可以通过ExposureConfiguration 类改变特定HTTP方法的暴露。这个特殊的配置类暴露了一个基于lambda的API来定义全局和基于类型的规则。
For example, we can use ExposureConfiguration to restrict PATCH requests against the UserRepository:
例如,我们可以使用ExposureConfiguration来限制针对UserRepository的 PATCH 请求。
public class RestConfig implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration restConfig,
CorsRegistry cors) {
ExposureConfiguration config = restConfig.getExposureConfiguration();
config.forDomainType(WebsiteUser.class).withItemExposure((metadata, httpMethods) ->
httpMethods.disable(HttpMethod.PATCH));
}
}
6. Conclusion
6.结语
In this article, we explored how we can configure Spring Data REST to customize the HTTP methods supported by default in our resources.
在这篇文章中,我们探讨了如何配置Spring Data REST以定制资源中默认支持的HTTP方法。
As usual, the examples used in this article can be found in our GitHub project.
像往常一样,本文中使用的例子可以在我们的GitHub项目中找到。