今天,我們宣佈用於 Cloudflare API 的 OpenAPI 結構描述正式發佈。這些 OpenAPI 結構描述透過 GitHub 發佈,並將隨著 Cloudflare 新增和更新 API 而定期更新。OpenAPI 是以機器可讀的格式定義 API 的廣泛採用標準。OpenAPI 結構描述允許將我們的 API 插入到各種工具中,以加速我們自己和客戶的開發。在內部,它將使我們更容易維護和更新我們的 API。在介紹這些好處之前,讓我們先從基礎知識開始。
什麼是 OpenAPI?
大部分網際網路都建立在 API(應用程式程式設計介面)之上,或者將它們作為服務提供給世界各地的客戶。這允許電腦以標準化的方式相互通訊。OpenAPI 是一種關於如何定義 API 的廣泛採用標準。這讓其他機器能夠可靠地剖析這些定義並以有趣的方式使用它們。Cloudflare 自己的 API Shield 產品使用 OpenAPI 結構描述來提供結構描述驗證,以確保只有格式正確的 API 請求才會傳送到您的源站。
Cloudflare 本身有一個 API,客戶可以使用它與網際網路上其他地方的安全性和效能產品進行互動。我們如何定義自己的 API?過去,我們使用稱為 JSON Hyper-Schema 的標準。這對我們很有幫助,但隨著時間的推移,我們希望採用更多的工具,既可以使自己內部受益,又可以使客戶的生活更輕鬆。OpenAPI 社群在過去幾年中蓬勃發展,提供了許多在使用 JSON Hyper-Schema 時無法提供的功能,我們將在後面進行討論。從今天開始,我們將使用 OpenAPI。
您可以在此處瞭解有關 OpenAPI 本身的更多資訊。擁有一個開放、易於理解的標準來定義我們的 API,就可以使用共用工具和基礎結構來讀取這些標准定義。讓我們看幾個範例。
Cloudflare 的 OpenAPI 結構描述的使用
大多數客戶不需要使用結構描述本身來查看價值。第一個利用 OpenAPI 結構描述的系統是我們今天推出的新 API 文件。因為我們現在有了 OpenAPI 結構描述,所以我們利用開放原始碼工具 Stoplight Elements 來協助產生這個新的文件網站。這讓我們能夠停用以前難以維護的定製網站。此外,Cloudflare 的許多工程師都熟悉 OpenAPI,因此我們的團隊可以更快地編寫新結構描述,並且透過使用團隊在定義新 API 時理解的標準來減少出錯的可能性。
但是,有一些方法可以直接利用結構描述。OpenAPI 社群擁有大量工具,只需要一組結構描述即可使用。模擬 API 和庫產生就是這樣的兩個範例。
模擬 Cloudflare 的 API
假設您有呼叫 Cloudflare API 的程式碼,並且您希望能夠輕鬆地在本地執行單元測試,或在 CI/CD 管道中執行整合測試。雖然您可以在每次執行時呼叫 Cloudflare 的 API,但出於一些原因,您可能不想這樣做。首先,您可能想要頻繁地執行測試,以至於管理資源的建立和卸除變得非常痛苦。此外,在許多此類測試中,您不一定會嘗試驗證 Cloudflare 中的邏輯,而是嘗試驗證您自己的系統行為。在這種情況下,模擬 Cloudflare 的 API 將是最佳做法,因為您可以確信自己沒有違反 Cloudflare 的 API 合約,又無需擔心管理實際資源的細節。此外,模擬讓您能夠模擬不同的場景,例如速率限制或接收 500 個錯誤。這讓您能夠針對通常可能產生嚴重影響的罕見情況測試程式碼。
例如,Stoplight Prism 可用於模擬 Cloudflare 的 API 進行測試。使用 Cloudflare API 結構描述的本機複本,您可以執行以下命令來啟動本機模擬伺服器:
然後,您可以向模擬伺服器傳送請求,以驗證您對 Cloudflare API 的使用不會在本地違反 API 合約:
$ docker run --init --rm \
-v /home/user/git/api-schemas/openapi.yaml:/tmp/openapi.yaml \
-p 4010:4010 stoplight/prism:4 \
mock -h 0.0.0.0 /tmp/openapi.yaml
這意味著更快的開發和更短的測試執行,同時仍然可以在 API 合併或部署之前儘早發現它們的合約問題。
$ curl -sX PUT localhost:4010/zones/f00/activation_check \
-Hx-auth-email:foo@bar.com -Hx-auth-key:foobarbaz | jq
{
"success": true,
"errors": [],
"messages": [],
"result": {
"id": "023e105f4ecef8ad9ca31a8372d0c353"
}
}
庫產生
Cloudflare 擁有多種程式設計語言的庫,例如 Terraform 和 Go,但我們並不支援所有可能的程式設計語言。幸運的是,使用像 openapi generator 這樣的工具,您可以輸入 Cloudflare 的 API 結構描述並產生各種語言的庫,然後在您的程式碼中使用它們來與 Cloudflare 的 API 對話。例如,您可以使用以下命令產生 Java 庫:
然後開始在您的 Java 程式碼中使用該用戶端與 Cloudflare 的 API 對話。
git clone https://github.com/openapitools/openapi-generator
cd openapi-generator
mvn clean package
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \
-i https://raw.githubusercontent.com/cloudflare/api-schemas/main/openapi.yaml \
-g java \
-o /var/tmp/java_api_client
Cloudflare 如何向 OpenAPI 轉換
如前所述,我們之前使用 JSON Hyper-Schema 來定義我們的 API。我們有大約 600 個已在結構描述中定義的端點。下面的程式碼片段展示了 JSON Hyper-Schema 中的端點是什麼樣子的:
讓我們看一下 OpenAPI 中的同一端點:
{
"title": "List Zones",
"description": "List, search, sort, and filter your zones.",
"rel": "collection",
"href": "zones",
"method": "GET",
"schema": {
"$ref": "definitions/zone.json#/definitions/collection_query"
},
"targetSchema": {
"$ref": "#/definitions/response_collection"
},
"cfOwnership": "www",
"cfPlanAvailability": {
"free": true,
"pro": true,
"business": true,
"enterprise": true
},
"cfPermissionsRequired": {
"enum": [
"#zone:read"
]
}
}
您可以看到,兩者看起來非常相似,並且在大多數情況下,它們都包含相同的資訊,包括方法類型、描述以及請求和回應定義(儘管它們在 $refs 中連結)。從一個結構描述移轉到另一個結構描述的價值不在於我們如何定義結構描述本身,而在於我們可以用這些結構描述做什麼。許多工具可以剖析 OpenAPI,但只有很少的工具可以剖析 JSON Hyper-Schema。
/zones:
get:
description: List, search, sort, and filter your zones.
operationId: zone-list-zones
responses:
4xx:
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/components-schemas-response_collection'
- $ref: '#/components/schemas/api-response-common-failure'
description: List Zones response failure
"200":
content:
application/json:
schema:
$ref: '#/components/schemas/components-schemas-response_collection'
description: List Zones response
security:
- api_email: []
api_key: []
summary: List Zones
tags:
- Zone
x-cfPermissionsRequired:
enum:
- '#zone:read'
x-cfPlanAvailability:
business: true
enterprise: true
free: true
pro: true
如果這個 API 是構成 Cloudflare API 的全部,那麼只需手動將 JSON Hyper-Schema 轉換為 OpenAPI 結構描述就可以了。然而,重複此動作 600 次將是一項艱巨的任務。考慮到團隊會不斷新增新的端點,這可以說是不可能維持的。我們現有的 API 文件也使用了現有的 JSON Hyper-Schema,這意味著我們需要在整個過渡期間使兩個結構描述保持最新。與這相比,肯定有更好的方法。
自動轉換
鑒於 JSON Hyper-Schema 和 OpenAPI 都是標準,因此應該可以輸入一種格式的檔案並將其轉換為另一種格式,對嗎?幸運的是,答案是肯定的!我們建置了一個工具,它擷取所有現有的 JSON Hyper-Schema 並輸出完全相容的 OpenAPI 結構描述。這當然不是一蹴而就的,但由於現有的 OpenAPI 工具,我們可以反覆改進自動轉換器,並在輸出結構描述上執行 OpenAPI 驗證工具,以查看轉換工具仍然存在哪些問題。
經過對轉換工具的多次反覆運算和改進,我們最終能夠從現有的 JSON Hyper-Schema 自動產生完全相容的 OpenAPI Spec 結構描述。在我們建置此工具時,團隊不斷新增和更新現有結構描述,我們的產品內容團隊也在不斷更新結構描述中的文字,以使我們的 API 文件更易於使用。這個過程的好處是我們不必減慢任何工作速度,因為舊結構描述中的任何變更都會自動反映在新結構描述中!
在工具準備就緒後,剩下的步驟就是決定何時以及如何停止對 JSON Hyper-Schemas 進行更新,並將所有團隊轉移到 OpenAPI 結構描述。(現在舊的)API 文件是最大的問題,因為它們只理解 JSON Hyper-Schema。感謝我們的開發人員體驗和產品內容團隊的幫助,我們今天才能夠發佈新的 API 文件,並且今天也可以正式切換到 OpenAPI!
接下來是什麼?
現在我們已經完全轉移到 OpenAPI,更多的機會就出現了。在內部,我們將研究我們可以採用哪些工具來幫助減少各個團隊的工作量並加快 API 開發。我們正在探索的一個想法是從程式碼標記法自動建立 openAPI 結構描述。在外部,我們現在擁有必要的基礎工具,可以開始探索如何自動產生和支援更多程式設計語言庫,以供客戶使用。我們也很期待看到大家使用結構描述獲得的成果,所以如果您做了一些很酷的事情或有什麼想法,請不要猶豫,與我們分享!