搶先一步
VMware 提供培訓和認證,以加速您的進程。
了解更多親愛的 Spring 社群,我們很榮幸地宣布 Spring HATEOAS 1.0 的第一個里程碑版本。Spring HATEOAS 已經開發了將近七年。最初只是 Spring MVC 的一個小擴展,後來成為 Spring Data REST 的基礎,並已成為 Spring MVC 應用程式中基於超媒體 API 的基本構建模組。
我們收到了來自社群關於更進階功能的許多意見,並最終決定將這些功能整合到程式庫中。此外,我們在使用該程式庫的過程中也獲得了大量的經驗,並認為我們應該藉此機會在 1.0 版本中反映這些經驗。
以下是摘要
全面檢修套件設計和領域模型語言。
升級至 Java 8 和 Spring Framework 5.1 作為基準。
透過 affordances API (HAL-FORMS、Collection+JSON、UBER) 提供進階超媒體支援。
超媒體支援 SPI 可插入自訂媒體類型實作。
Spring WebFlux 的 LinkBuilder
實作。
完全檢修 參考文件。
讓我們詳細了解一下其中一些功能。
在發布 1.0 之前,我們藉此機會重新評估了套件結構以及我們在領域類型中公開的術語。與我們的 0.x 版本相比,這導致了一些相當重大的變更。
最根本的變更是 Spring HATEOAS 不會建立資源。這是 Spring MVC/Spring WebFlux 的功能。我們建立廠商中立的 超媒體表示法。因此,我們重新命名了這些核心類型
ResourceSupport
現在是 RepresentationModel
Resource<T>
現在是 EntityModel<T>
Resources<T>
現在是 CollectionModel<T>
PagedResources<T>
現在是 PagedModel<T>
作為副作用,ResourceAssembler
現在是 RepresentationModelAssembler
,其方法現在是 toModel(…)
和 toCollection(…)
。程式碼庫中還有類似的變更反映了此變更。
許多 API 都以 List<Link>
的概念為中心,包括 RepresentationModel.getLinks()
。我們現在傳回 Links
而不是 Java 列表,它經過了顯著的增強,使其更容易組合、提取和合併連結。核心抽象 LinkBuilder
、EntityLinks
、RelProvider
、LinkDiscoverer
分別被分組到 server
和 client
套件中。
聽起來很複雜?別擔心。我們 編寫了一個指令碼,該指令碼將盡最大努力將您的大部分程式碼移轉到新的類型和 import 語句。它可能無法涵蓋所有內容,但應該可以大大簡化移轉。
此版本中最關鍵的功能之一是支援 Spring WebFlux 和反應式程式設計。這包括
以反應方式建立連結。
將超媒體提供給 WebFlux 端點。
支援 WebFlux 的 WebClient
來使用超媒體。
Spring HATEOAS 隨附 WebFluxLinkBuilder
,因此您可以以反應方式建立連結。它將自動擷取伺服器託管的基底 URI,並將其與端點的路徑合併。
範例 1. 以反應方式建立連結和 affordances
import static org.springframework.hateoas.server.reactive.WebFluxLinkBuilder.*;
@GetMapping("/employees")
public Mono<CollectionModel<EntityModel<Employee>>> all() {
var controller = methodOn(WebFluxEmployeeController.class);
return Flux.fromIterable(EMPLOYEES.keySet())
.flatMap(id -> findOne(id))
.collectList()
.flatMap(resources -> linkTo(controller.all()).withSelfRel() (1)
.andAffordance(controller.newEmployee(null)) (2)
.andAffordance(controller.search(null, null))
.toMono() (3)
.map(selfLink -> new CollectionModel<>(resources, selfLink)));
}
連結到具有 Reactor 類型的 WebFlux 端點。
以對領域友好的方式新增 affordances(閱讀以下更多內容)。
傳回 Mono
,以便您可以執行任何額外的 Reactor 作業。
假設此控制器託管在 http://example.com,則預期會提供具有連結到 http://example.com/employees 的超媒體文件。
除了以反應方式建立連結之外,當您傳回基於 RepresentationModel
的類型(無論是否包裝在 Reactor 類型中)時,您的 WebFlux 端點現在將呈現超媒體。
過去兩年來我們一直在開發的是 Affordances。我們從 Escalon 的 @dschulten 和 HDIV Security 的 @anderruiz 團隊那裡獲得了寶貴的意見,了解如何收集元資料以呈現更進階的媒體類型,這些媒體類型比已經支援的 HAL 更詳細地描述資源互動。您在上面的 WebFlux 端點中看到了該元資料收集 API 的片段。
透過將相關操作連結在一起,可以產生可識別 affordance 的媒體類型,例如 HAL-FORMS(如下所示)
範例 2. 從 affordance API 產生的 HAL-FORMS 範例輸出
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"role" : "ring bearer",
"_links" : {
"self" : {
"href" : "https://127.0.0.1:8080/employees/1"
}
},
"_templates" : {
"default" : {
"title" : null,
"method" : "put",
"contentType" : "",
"properties" : [ {
"name" : "firstName",
"required" : true
}, {
"name" : "lastName",
"required" : true
}, {
"name" : "role",
"required" : true
} ]
},
"partiallyUpdateEmployee" : {
"title" : null,
"method" : "patch",
"contentType" : "",
"properties" : [ {
"name" : "firstName",
"required" : false
}, {
"name" : "lastName",
"required" : false
}, {
"name" : "role",
"required" : false
} ]
}
}
}
這種可識別 affordance 的媒體類型提供了執行此資源更新所需的所有資訊。
說到 HAL-FORMs,我們新增了多個新的媒體類型
但為什麼要停在這裡?雖然我們計劃支援其他媒體類型,但不應阻止您建立自己的媒體類型。我們引入了一個新的 SPI,可讓您編寫 您自己的自訂媒體類型,並將其註冊到 Spring HATEOAS,以便您可以將其與 Spring MVC、RestTemplate
bean、Spring WebFlux 和 WebClient
bean 搭配使用。
不確定您是否注意到,但 Spring 團隊一直在升級其所有文件。我們也是!我們也開始 清理和檢修內容,因此請務必瀏覽一下。我們將在即將到來的里程碑版本中對此進行更多調整。有任何遺漏嗎?請告訴我們!超過 80 個已關閉的問題,請務必查看一下。並告訴我們您的想法!
不能在不提及 Spring Data REST 的情況下討論 Spring HATEOAS。
Spring HATEOAS 的所有這些變更都在 Spring Data REST 的最新快照版本中被採用和調整。總體計劃是讓 Spring Data - Release train Moore 升級到 Spring HATEOAS 1.0。這意味著像 affordances 和新的媒體類型將成為 Spring Data REST 的一部分。
Spring HATEOAS 1.0 現在是基於 Spring Framework 5.1。這表示像是 Forwarded 標頭的處理將委派給 Spring Framework 管理。如果您的應用程式前端的 Proxy 伺服器正在發送正確的標頭,而您使用 Spring HATEOAS 的 API 突然沒有重新編寫 URI,則您需要設定標頭處理。
如果您正在使用 Spring Boot,這就是您所需要的一切
server.use-forward-headers=true
如果您沒有使用 Spring Boot,那麼您必須設定如下所示的內容
@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
var filter = new FilterRegistrationBean<>();
filter.setFilter(new ForwardedFilter());
return filter;
}
更多詳細資訊,請查看Spring Framework 的 Forwarded 標頭過濾器。
請查看下面的專案連結。
作為一個里程碑版本,您可以在 https://repo.spring.io/libs-milestone 找到相關元件。