Micronaut 中的 API 版本控制
1. 概述
在本教程中,我們將討論如何利用Micronaut Framework功能來實現不斷發展的 REST API。
在不斷發展的軟體開發專案中,有時純粹基於 REST API,在引入新功能和改進的同時保持向後相容性是一項至關重要的挑戰。實現這一目標的基本面向之一是我們必須實現一種稱為 API 版本控制的技術。
我們將在 Micronaut 的背景下探索 API 版本控制的概念,Micronaut 是一種流行的微服務框架,用於建立高效且可擴展的應用程式。我們將深入探討 API 版本控制的重要性、在 Micronaut 中實現它的不同策略,以及確保版本平穩過渡的最佳實踐。
2. API 版本控制的重要性
API 版本控制是管理和發展應用程式介面 (API) 的做法,以允許客戶端繼續使用現有版本,同時在準備就緒時採用新版本。出於多種原因,它是必不可少的。
2.1.保持相容性
隨著應用程式的發展,我們可能需要更改 API 以引入新功能、修復錯誤或提高效能。然而,也必須確保此類變更不會幹擾現有客戶。 API 版本控制使我們能夠引入更改,同時保持與先前版本的兼容性。
2.2.允許逐步採用
我們的 API 的客戶可能有不同的採用新版本的時間表。因此,提供多個版本的 API 可以讓客戶在合理的採用時間內更新其程式碼,從而降低破壞應用程式的風險。
2.3.促進協作
它也促進了開發團隊之間的協作。當不同的團隊處理系統的其他部分,或第三方開發人員與我們的 API 整合時,版本控制允許每個團隊擁有穩定的介面,即使在其他地方進行更改也是如此。
3. Micronaut 中的 API 版本控制策略
Micronaut 提供了不同的策略來實作 API 版本控制。我們不會討論哪一個是最好的,因為它很大程度上取決於用例和專案的實際情況。儘管如此,我們可以討論其中每一項的具體細節。
3.1. URI 版本控制
在 URI 版本控制中,API 的版本在 URI 中定義。這種方法可以清楚地表明客戶端正在使用哪個版本的 API 。儘管 URL 可能不太用戶友好,但它向客戶端闡明了它使用的版本。
@Controller("/v1/sheep/count")
public class SheepCountControllerV1 {
@Get(
uri = "{?max}",
consumes = {"application/json"},
produces = {"application/json"}
)
Flowable<String> countV1(@Nullable Integer max) {
// implementation
儘管可能不切實際,但我們的客戶對所使用的版本很確定,這意味著透明度。從開發方面來看,很容易實現特定於特定版本的任何業務規則,這意味著良好的隔離等級。然而,有人可能會認為這是一種侵入性的做法,因為 URI 可能會頻繁更改。它可能需要客戶端進行硬編碼,並添加不完全特定於資源的額外上下文。
3.2.標頭版本控制
實現 API 版本控制的另一個選項是利用標頭將請求路由到正確的控制器。這是一個例子:
@Controller("/dog")
public class DogCountController {
@Get(value = "/count", produces = {"application/json"})
@Version("1")
public Flowable<String> countV1(@QueryValue("max") @Nullable Integer max) {
// logic
}
@Get(value = "/count", produces = {"application/json"})
@Version("2")
public Flowable<String> countV2(@QueryValue("max") @NonNull Integer max) {
// logic
}
}
透過簡單地使用@Version
註釋,Microunat 可以根據標頭的值將請求重定向到正確的處理程序。但是,我們仍然需要更改一些配置,如下所示:
micronaut:
router:
versioning:
enabled: true
default-version: 2
header:
enabled: true
names:
- 'X-API-VERSION'
現在,我們剛剛透過 Micronaut 啟用了版本控制,將版本 2 定義為預設版本,以防未指定版本。使用的策略將是基於標頭的,標頭X-API-VERSION
將用於確定版本。實際上,這是 Micronaut 查看的預設標頭,因此在這種情況下,不需要定義它,但如果我們想使用另一個標頭,我們可以這樣指定它。
使用標頭,URI 保持清晰簡潔,我們可以保持向後相容性,URI 是純粹基於資源的,並且它允許 API 的發展更加靈活。然而,它不太直觀和可見。客戶必須知道他想要使用的版本,而且它更容易出錯。還有另一種類似的策略,其中包括使用 MineTypes 來實現此目的。
3.3.參數版本控制
此策略利用 URI 中的查詢參數來進行路由。在 Mircronaut 中的實施方面,它與先前的策略完全相同。我們只需要在控制器中加入@Version。但是,我們需要更改一些屬性:
micronaut:
router:
versioning:
enabled: true
default-version: 2
parameter:
enabled: true
names: 'v,api-version'
這樣,客戶端只需在每個請求中傳遞v
或api-version
作為查詢參數,Micronat 就會為我們處理路由。
當再次使用此策略時,URI 將沒有與資源相關的信息,儘管比不必更改 URI 本身要少。除此之外,版本控制不太明確,也更容易出錯。這不是 RESTful,需要文件以避免混淆。然而,我們也可以體會到該解決方案的簡單性。
3.4.自訂版本控制
Micronaut 還提供了一種自訂方法來實作 API 版本控制,我們可以在其中實作版本控制路由解析器並顯示 Micronaut 要使用哪個版本。實作很簡單,我們只需要實作一個介面即可,如下例:
@Singleton
@Requires(property = "my.router.versioning.enabled", value = "true")
public class CustomVersionResolver implements RequestVersionResolver {
@Inject
@Value("${micronaut.router.versioning.default-version}")
private String defaultVersion;
@Override
public Optional<String> resolve(HttpRequest<?> request) {
var apiKey = Optional.ofNullable(request.getHeaders().get("api-key"));
if (apiKey.isPresent() && !apiKey.get().isEmpty()) {
return Optional.of(Integer.parseInt(apiKey.get()) % 2 == 0 ? "2" : "1");
}
return Optional.of(defaultVersion);
}
}
在這裡,我們可以看到如何利用請求中的任何資訊來實施路由策略,而 Micronaut 會完成剩下的工作。這很強大,但我們需要謹慎,因為這可能會導致版本控制的實作形式較差且不太直觀。
4。結論
在本文中,我們了解如何使用 Micronaut 實作 API 版本控制。此外,我們也討論了應用該技術的不同策略及其一些細微差別。
同樣清楚的是,選擇正確的策略需要權衡 URI 清潔性、版本控制的明確性、易用性、向後相容性、RESTful 遵守以及使用 API 的客戶端的特定需求的重要性。最佳方法取決於我們專案的獨特要求和限制。
與往常一樣,本文中使用的所有程式碼範例都可以在 GitHub 上找到。