1. 簡介
Spring Data REST 可以移除大量的 REST 服務中常見的冗餘代碼。
在本教程中,我們將探索如何自定義 Spring Data REST 的 HTTP 綁定默認值。
2. Spring Data REST Repository Fundamentals
為了開始,讓我們創建一個空接口,該接口擴展了 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/
將返回 HTTP 狀態 204 (沒有內容返回) 以確認刪除。
現在,假設 我們希望隱藏 delete 方法供第三方使用,同時又能內部使用它。
我們可以首先將 deleteById 方法簽名添加到我們的接口中,這會向 Spring Data REST 信號我們正在配置它。
然後,我們可以使用註解 @RestResource(exported = false),這會 配置 Spring 跳過此方法在觸發 HTTP 方法暴露時:
@Override
@RestResource(exported = false)
void deleteById(Long aLong);
現在,如果我們重複上面的 cUrl 命令,我們將收到 HTTP 狀態 405 (方法不允許)。
4. 自定義支持的HTTP方法
@RestResource註解也賦予我們自定義映射到存儲方法以及HATEOAS資源發現返回的鏈接ID的URL路徑的能力。
要做到這一點,我們使用註解的可選參數:
- path 用於URL路徑
- rel 用於鏈接ID
讓我們回到我們的UserRepository並添加一個簡單的findByEmail方法:
WebsiteUser findByEmail(@Param("email") String email);
通過執行一個cUrl到http://localhost:8080/users/search/,我們可以現在看到我們的新方法列出與其他資源:
{
"_links": {
"findByEmail": {
"href": "http://localhost:8080/users/search/findByEmail{?email}"
},
"self": {
"href": "http://localhost:8080/users/search/"
}
}
}
如果我們不喜歡默認路徑,而不是更改存儲方法,我們可以簡單地添加@RestResource註解:
@RestResource(path = "byEmail", rel = "customFindMethod")
WebsiteUser findByEmail(@Param("email") String email);
並且如果我們在資源發現中再次執行,結果的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 請求,都使用相同的 save 方法。
從 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 方法。