在Spring Data REST中自定义HTTP端点

2023/05/18

1. 简介

Spring Data REST可以消除许多对REST服务来说很自然的样板代码。在本教程中,我们将探讨如何自定义一些Spring Data REST的HTTP绑定默认值

2. Spring Data REST Repository基础

首先,我们创建一个扩展CrudRepository接口的空接口,指定实体的类型及其主键的类型:

public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}

默认情况下,Spring生成所有需要的映射,将每个资源配置为可通过适当的HTTP方法访问,并返回适当的状态码。

如果我们不需要CrudRepository中定义的所有资源,我们可以扩展基本的Repository接口并只定义我们需要的资源:

public interface UserRepository extends Repository<WebsiteUser, Long> {
    void deleteById(Long aLong);
}

收到请求后,Spring读取使用的HTTP方法,并根据资源类型调用接口中定义的适当方法(如果存在),否则返回HTTP状态码405(Method Not Allowed)。

参考上面的代码,当Spring收到DELETE请求时,它会执行我们的deleteById方法。

3. 限制公开哪些HTTP方法

假设我们有一个用户管理系统,那么我们可能会有一个UserRepository。而且,由于我们使用的是Spring Data REST,因此通过扩展CrudRepository可以获得很多功能:

@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends CrudRepository<WebsiteUser, Long> {}

我们的所有资源都使用默认的CRUD模式公开,因此发出以下请求:

curl -v -X DELETE http://localhost:8080/users/<existing_user_id>

这将返回HTTP状态码204(No Content returned)以确认删除。

现在,假设我们想对第三方隐藏delete方法,同时又能在内部使用它。我们可以首先将deleteById方法签名添加到我们的接口中,该签名向Spring Data REST发出信号,表示我们将对其进行配置。然后,我们可以使用注解@RestResource(exported = false),它将配置Spring在触发HTTP方法公开时跳过此方法

@Override
@RestResource(exported = false)
void deleteById(Long aLong);

现在,如果我们再次运行上面相同的cUrl命令,得到的HTTP状态码将是405(Method Not Allowed)。

4. 自定义支持的HTTP方法

@RestResource注解还允许我们能够自定义映射到Repository方法的URL路径以及HATEOAS资源发现返回的JSON中的链接ID 。

为此,我们使用注解的几个可选参数:

  • path:URL路径
  • rel:链接ID

因此,我们向UserRepository添加一个简单的findByEmail方法:

WebsiteUser findByEmail(@Param("email") String email);

通过访问http://localhost:8080/users/search/,我们现在可以看到与其他资源一起列出的新方法:

{
    "_links": {
        "findByEmail": {
            "href": "http://localhost:8080/users/search/findByEmail{?email}"
        },
        "self": {
            "href": "http://localhost:8080/users/search/"
        }
    }
}

如果我们不喜欢默认路径,而不是更改Repository方法,我们可以简单地添加@RestResource注解

@RestResource(path = "byEmail", rel = "customFindMethod")
WebsiteUser findByEmail(@Param("email") String email);

如果我们再次访问http://localhost:8080/users/search/,可以看到返回JSON中的更改:

{
    "_links": {
        "customFindMethod": {
            "href": "http://localhost:8080/users/search/byEmail{?email}",
            "templated": true
        },
        "self": {
            "href": "http://localhost:8080/users/search/"
        }
    }
}

5. 编程配置

有时我们需要更细粒度的配置来公开或限制对我们的HTTP方法的访问。例如,对集合资源的POST,以及对元素资源的PUT和PATCH,都使用相同的保存方法。

从Spring Data REST 3.1和Spring Boot 2.1开始,我们可以通过ExposureConfiguration类更改特定HTTP方法的公开。这个特定的配置类公开了一个基于lambda的API来定义全局规则和基于类型的规则。

例如,我们可以使用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. 总结

在本文中,我们探讨了如何配置Spring Data REST来自定义资源中默认支持的HTTP方法。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章