1. 引言
軟件工程行業越來越依賴 Web API。雲計算和 HTTP 的日益普及或許可以解釋這一現象。
一個軟件開發團隊必須確保他們設計出有益且用户友好的 API。 在傳統的開發方法中,主要的挑戰在於如何在同時保持敏捷性,同時創建 API 契約和實現新產品的業務邏輯。
在本文中,我們將介紹使用 Spring Boot 和 OpenAPI 規範 3.0 的 API-First 開發方法。 這種方法通過及時的 API 設計反饋、快速失敗流程和並行工作,提高了團隊的溝通和敏捷性。
2. 什麼是 OpenAPI 規範
OpenAPI 規範 (OAS) 標準化了創建 API 設計文檔的方法。 在使用 OAS 的 API-First 流程中,典型的工作流程如下:
- 團隊創建設計文檔並與相關人員分享,以獲取反饋並進行迭代修改。
- 當團隊和利益相關者就 API 設計達成一致時,開發人員使用該文檔生成服務器端骨架代碼,使用文檔生成工具。
- 最後,開發人員使用先前生成的代碼實現 API 的業務邏輯。
OAS 3.1 允許指定 HTTP 資源、動詞、響應代碼、數據模型、媒體類型、安全方案和其他 API 組件。
3. 使用 API-優先開發的原因
敏捷開發是軟件行業中最常用的方法論之一。 敏捷意味着儘快構建一個小的東西,以便快速失敗並更改初始設計,或者繼續逐步添加小的更改。
從敏捷團隊的角度來看,API-優先開發具有幾個優勢:
- 提供了一種快速反饋 API 設計的方式。
- 創建一個通向 API 合同協議的單一溝通渠道。
- 允許參與 API 設計的人員並行工作。
為了充分理解 API-優先方法的優勢,我們將比較兩支敏捷團隊的工作流程場景。 第一支團隊使用傳統方法,而第二支團隊使用 API-優先開發:
在傳統場景中,開發人員被分配到構建新產品功能上。 通常,該開發人員首先實現業務邏輯,然後將該邏輯連接到代碼中的 API 設計。 因此,API 在開發人員完成該功能的全部代碼更改後,才對利益相關者進行審查。 這導致了緩慢和關於 API 合同審查和協議的溝通不暢。
在 API-優先開發中,設計師在業務邏輯開發階段創建 API 合同文檔。 該文檔為產品利益相關者提供了一種共同的語言,以評估構建工作量、提供及時反饋、創建測試用例、文檔化 API 等。
因此,我們可以通過更改初始設計或繼續使用它,在浪費時間開發應用程序之前,變得更加敏捷。
另一個使用 API-優先開發的原因是,在創建文檔後,多個人可以並行地在同一產品功能上工作,例如:
- 產品經理評估風險、創建新功能並管理時間。
- 質量保證分析師構建測試場景。
- 技術作家文檔化 API。
- 開發人員實現業務邏輯代碼。
4. 定義 API 契約
我們將使用一個銀行演示 REST API 來闡述 API-First 方法的工作流程。該 API 允許執行兩個操作:獲取餘額和存款金額。下表顯示了這些操作的資源路徑、HTTP 謂詞和響應碼 (RC):
| HTTP 謂詞 | 資源 | 錯誤 RC | 成功 RC | |
|---|---|---|---|---|
| 獲取餘額 | GET | /account | 404 – 賬户未找到 | 200 – 獲取餘額信息 |
| 存款金額 | POST | /account/deposit | 404 – 賬户未找到 | 204 – 存款操作完成 |
現在,我們可以創建 OAS API 規範文件。我們將使用 Swagger Online Editor,這是一個用於解釋 YAML 到 Swagger 文檔的在線解決方案。
4.1. API 頂層上下文
首先,讓我們定義 API 的頂層上下文。為此,請前往 Swagger Editor,並將編輯器左側的內容替換為以下 YAML 代碼:
openapi: 3.0.3
info:
title: Banking API Specification for account operations
description: |-
A simple banking API that allows two operations:
- get account balance given account number
- deposit amount to a account
version: 1.0-SNAPSHOT
servers:
- url: https://testenvironment.org/api/v1
- url: https://prodenvironment.org/api/v1
tags:
- name: accounts
description: Operations between bank accounts注意:目前忽略這些錯誤,它們不會阻礙我們的工作流程,隨着我們進入下一部分,它們會消失。
讓我們逐個檢查每個關鍵詞:
- openapi – 使用的 OAS 版本。
- title – API 的簡短標題。
- description – API 的職責描述。
- version – API 的當前版本,例如 1.0-SNAPSHOT。
- servers – 客户端可以訪問 API 的可用機器。
- tags – 用於將 API 操作分組為子集的一組唯一標籤。
4.2. 公開 API 路徑
現在,讓我們創建前面描述的 GET /account</em/> 和 POST /account/deposit</em/> API 端點。 要做到這一點,請在 YAML 編輯器的根級別添加以下內容:
paths:
/account:
get:
tags:
- accounts
summary: Get account information
description: Get account information using account number
operationId: getAccount
responses:
200:
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
404:
description: Account not found
content:
application/json:
schema:
$ref: '#/components/schemas/AccountNotFoundError'
/account/deposit:
post:
tags:
- accounts
summary: Deposit amount to account
description: Initiates a deposit operation of a desired amount to the account specified
operationId: depositToAccount
requestBody:
description: Account number and desired amount to deposit
content:
application/json:
schema:
$ref: '#/components/schemas/DepositRequest'
required: true
responses:
204:
description: Success
404:
description: Account not found
content:
application/json:
schema:
$ref: '#/components/schemas/AccountNotFoundError'注意:再次提醒,YAML 解釋器會顯示一些錯誤,我們將在第 4.3 節中解決它們。目前可以忽略這些錯誤。
文檔中包含了很多內容。為了便於理解,我們將其分解為各個部分,逐個分析關鍵詞:
- paths – 定義 API 資源 /account 和/account/deposit。 在資源下,必須定義可用的 get 和 post 動詞。
- tags – 它所屬的組。應與第 4.1 節中描述的相同標籤名稱。
- summary – 端點所做事情的簡要信息。
- description – 關於端點工作方式的詳細信息。
- operationId – 描述操作的唯一標識符。
- requestBody – 包含 description、content 和 required 關鍵詞的請求負載。我們將在第 4.3 節中定義內容 schema。
- responses – 所有可用響應代碼的列表。每個響應代碼對象包含 description 和 content 關鍵詞。我們將定義該內容 schema 在第 4.3 節中。
- content: 消息的 HTTP Content-Type。
4.3. 定義數據模型組件
最後,讓我們為我們的 API 創建數據模型對象:請求和響應主體以及錯誤消息。要實現這一點,請在 YAML 編輯器的根級別添加以下結構:
components:
schemas:
Account:
type: object
properties:
balance:
type: number
AccountNotFoundError:
type: object
properties:
message:
type: string
DepositRequest:
type: object
properties:
accountNumber:
type: string
depositAmount:
type: number在添加了上述內容後,編輯器的所有解釋錯誤都應該消失。
在上述 YAML 代碼中,我們定義了與第 4.2 節的 schema 關鍵詞中相同的組件。我們可以像使用組件一樣,隨意地重複使用它們。例如,AccountNotFoundError 對象被用於兩個端點的 404 響應代碼中。讓我們分別檢查代碼中的關鍵詞:
- components – 組件的根級別關鍵詞。
- schemas – 所有對象定義的列表。
- type – 字段的類型。如果使用 object 類型,我們還需要定義 properties 關鍵詞。
- properties – 所有對象字段名稱及其類型的列表。
4.4. 審核 API 文檔
此時,API已上線供產品相關方進行審核。我們知道 API-First 開發的主要優勢在於能夠快速失敗或成功,而無需在開發階段浪費時間。因此,請確保每個人都審核並與擬議的 API 資源、響應代碼、數據模型以及 API 的描述和職責進行協作,然後再進入開發階段。
在團隊達成設計方案後,他們可以並行地開發 API。
5. 將 YAML 文檔導入 Spring Boot 應用
本節介紹了開發者如何將 YAML 文檔導入應用程序並自動生成 API 骨架代碼。
首先,我們需要在 /src/main/resources 目錄下創建一個名為 account_api_description.yaml 的空 YAML 文件。然後,我們將 account_api_description.yaml 文件中的內容替換為 Swagger 在線編輯器中的完整 YAML 代碼。最後,我們需要將 openapi-generator-maven-plugin 插件添加到 Spring Boot Application 的 <plugins> 標籤中,位於 pom.xml 文件中:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.2.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<skipValidateSpec>true</skipValidateSpec>
<inputSpec>./src/main/resources/account_api_description.yaml</inputSpec>
<generatorName>spring</generatorName>
<configOptions>
<openApiNullable>false</openApiNullable>
<interfaceOnly>true</interfaceOnly>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>您可以在 OpenAPI 插件教程中找到此處使用的代碼。
現在,讓我們通過運行以下命令從 YAML 文件生成服務器端代碼:
mvn clean install之後,我們可以檢查生成的代碼在 target 文件夾中:
從那裏,開發人員可以使用生成的類作為開發階段的起點。例如,我們可以使用下面的 AccountApi 接口,並使用 AccountController 類:
@Controller
public class AccountController implements AccountApi {
@Override
public ResponseEntity<Void> depositToAccount(DepositRequest depositRequest) {
//Execute the business logic through Service/Utils/Repository classes
return AccountApi.super.depositToAccount(depositRequest);
}
@Override
public ResponseEntity<Account> getAccount() {
//Execute the business logic through Service/Utils/Repository classes
return AccountApi.super.getAccount();
}
}被覆蓋的方法 depositToAccount 和 getAccount 分別對應於 POST /account/deposit 和 GET /account 端點。
6. 結論
在本文中,我們學習瞭如何使用 API-First 開發方法,結合 Spring-Boot 和 OAS。我們還探討了 API-First 的優勢以及它如何幫助現代敏捷軟件開發團隊。使用 API-First 的最重要原因在於它提高了敏捷性和在創建 API 時減少了浪費的時間。通過這種方法,我們可以更快地進行設計草案、迭代更改和提供反饋。
另一個使用 API-First 方法的好理由是利益相關者無需等待開發人員完成代碼即可開始工作。QA 工程師、作家、經理和開發人員在初始 API 設計文檔創建後,可以並行工作。