基於OAS設計可擴充套件OpenAPI
隨著網際網路行業的興起,開發模式已逐步轉換為微服務自治:小團隊開發微服務,然後通過Restful介面相互呼叫。開發者們越來越渴望能夠使用一種“官話”進行流暢的溝通,甚至實現多種程式語言系統的自動化互動。
開放API戰略(Open API Initiativev)於2017年1月發表宣告,2月釋出實現草案,經過反覆討論, 標準API規範OAS(OpenAPI-Specification)3.0版本在2017年6月誕生。
OAS 3.0架構中將OpenAPI賦予了以下8個模組的定義,其中黃色模組為必選欄位,綠色模組為可選欄位:
各個主要模組工作流如下所示:
以下重點說明使用者獲取使OAS API資訊的三個必選部分:
1.1 API基本資訊
使用者查詢獲取OpenAPI的基本定義及資訊,涉及以下兩個模組內容:
l openapi
是否必選:必選
物件型別:String
類似於XML宣告(<?xml version="1.0"?> ),用於設定檔案應該使用哪一種規範進行解析。
l info
是否必選:必選
物件型別:Info Object
這個模組主要提供API的元資料。
以下為一個Info Object樣例:
title: Sample Pet Store App #必須,應用名稱
description: This is a sample server for apetstore. #應用的描述
termsOfService: http://example.com/terms/ #應用的服務條款連線
contact: #應用提供商的聯絡方式
name: API Support
url: http://www.example.com/support
email: [email protected]
license: #應用所遵循的協議
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.1 #應用版本
1.2 目標伺服器資訊
使用者查詢獲取伺服器的基本定義及資訊,涉及以下模組資訊:
servers
是否必選:必選
物件型別:[Server Object]
這個模組主要提供和目標伺服器的連線資訊,如果這個模組沒有定義url,根據規範會自動生成一個url為/的Server Object。
例如:
servers:
- url: https://development.gigantic-server.com/v1 #必選,
description: Development server #非必選,url描述
1.3 API路徑及定義
查詢API具體引數,涉及OAS剩餘的模組,本文主要介紹paths和components模組。
l paths
是否必選:必選
物件型別:Paths Object
這個模組主要提供OpenAPI所在的目標伺服器的連線資訊,如果這個模組沒有定義,根據規範會自動生成一個url為/的Server Object。通過多級定義,分別確定API的paths/method,並且通過$ref引用comonents模組中的定義,可以複用響應碼等相關資訊。對於攜帶body體的請求型別,requestBody可以提供example(或陣列examples),這是非常靈活的(可以傳入一個完整的例子,一個參考,甚至是一個URL的例子)。
例如:
/pets: #URL
get: #方法,get/post/..
description: Returns all pets . #描述
responses: #響應模組
'200': #返回碼為200,可以使用萬用字元定義響應
description: A list of pets. #響應描述
content: #Content欄位
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/pet' #引用componets
l components
是否必選:非必選
物件型別:Components Object
這個模組主要提供每個OpenAPI自定義的欄位定義,這部分定義的物件往往被paths中具體API進行引用:
− 響應 responses
− 引數 parameters
− 示例 examples
− 請求體 requestBodies
− 標題 headers
− 連結 links
− 回撥 callbacks
− 模式 schemas
− 安全體系 securitySchemes
以下為一個Components Object樣例:
components:
schemas: #協議定義
Category:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
parameters: #引數定義
skipParam:
name: skip
in: query
description: number of items to skip
required: true
schema:
type: integer
format: int32
limitParam:
name: limit
in: query
description: max records to return
required: true
schema:
type: integer
format: int32
responses: #返回資訊定義
NotFound:
description: Entity not found.
IllegalInput:
description: Illegal input for operation.
GeneralError:
description: General Error
content:
application/json:
schema:
$ref: '#/components/schemas/GeneralError'
securitySchemes:
api_key:
type: apiKey
name: api_key
in: header
petstore_auth: #認證定義
type: oauth2
flows:
implicit:
authorizationUrl: http://example.org/api/oauth/dialog
scopes:
write:pets: modify pets in your account
read:pets: read your pets
2 如何使用OAS 設計可擴充套件的OpenAPI
OpenAPI規範包含一組有關如何設計REST API的強制性準則,首推協議優先的方法,而非實現優先,因此需要首先設計API介面,然後實現協定介面的程式碼。
如何實現一個優雅的API是一個非常具有挑戰性的工作,開發者需要在龐大的後端系統的支援下,通過合適的方式將API暴露出去,除去單詞拼寫,路徑設計等以外,設計優良的OpenAPI往往具有以下特性:
l 單一職責
單一職責是軟體工程中一條著名的原則,實際在設計API時應確保每個API具有單一核心的職責,當某個API職責發生改變時不應該導致其他API發生故障和風險。OAS中不同的API可以在paths模組中引用多個schema,當我們設計新的API或者擴充套件原有API功能時,如果發現多個API多次引用相同schema,需重點審視每個API是否仍然保持單一職責。
l 抽象API
合適的抽象API 與業務無關的,更通用,而且方便擴充套件。 具體的API介面設計能解決特定的問題,但是在系統的擴充套件性和普遍適用性上則相應欠缺,因此需要針對特定的場景分析,避免over-designed(過度設計)和under-engineering(懶惰設計)。
舉個簡單的例子,我們設計一個paths為/dog的API,那麼這個API返回的是具體dog的相關資訊,而如果我們進行抽象設計一個paths為/pet的API,將dog作為引數配置在components的parameters中,這樣該API的擴充套件性進行了提升,後續擴充套件其他寵物比如cat的業務可以在不改變API路徑的基礎上進行開發,只需要更新component的parameters即可。
l 收斂API
提供給使用者的OpenAPI最好支援批量資料處理,而不是讓使用者一次一次地呼叫。通過考慮多個API間的關聯性,讓使用者體會到API的簡潔性。舉例來說,如果使用者有可能在呼叫 API2之前需要API1的結果,那麼API提供者應該把API1和API2進行包裝。這會減輕使用者的記憶負擔,API收斂需要符合最少知識的原則,作為使用者應該對他所使用的系統有最少的瞭解,而不是過多介入到系統的細節中,因此在設計API時候,在滿足使用者訴求的情況下,components模組欄位越少越好。設計者往往容易在收斂API時候出現無法保證單一職責的原則的情況,好的設計需要在兩者之間取得一個平衡,聚焦於最終的目的:讓使用者快好省的用起來。
l 擴充套件機制
在設計API時需要考慮未來可擴充套件性,為後續API相容歷史API提供支援。一方面便於開發者自身增加功能,另一方面使用者也能參與進來,共建API生態。通過設計定義OAS,可以方便的按照OAS架構設計出面向物件、擴充套件性良好的API。
l 版本控制
版本控制其實是擴充套件的一部分,鑑於大量專案在版本控制方面都做的比較糟糕,諸如隨心所欲的版本命名、前後格式不一致的版本設定、沒有規範的功能迭代,因此在大版本號不變的情況下,需要保障API向前相容。當API的大版本號改動時,意味著API整體有大的改動,很可能不相容之前的API,同時可以提醒使用者需要查詢API更新文件進行適配,否則使用者可能在更新API之後出現各種各樣難以預測的故障。反之,如果修改小版本號則意味著這是個向前相容的優化升級,使用者可以在例行更新中採用新的API。這種和使用者約定好的默契,可以激發使用者採用新版本的熱情,而不是永遠不升級依賴。
l 面向擴充套件開發
在通過OAS定義完相關資訊之後,優雅的OpenAPI在開發過程中應著重思考API的可配置性,API的實現應該面向修改開放的,因此需要將相關諸如引數校驗、欄位長度等配置項進行抽取,在提供預設配置項的前提下可配置可修改,同時應當允許配置項的新增,例如引入java的可變引數型別等,這樣當OAS文件進行修改時,可以儘可能的較少整體API實現的變動量。
以上列舉了優雅的OpenAPI所具有的部分特性,與其說OAS設計規範是一個強制的法則,不如說是一種引導式框架,開發者通過遵循規範從而實現高效的敏捷迭代。
當完成OpenAPI的設計開發之後,我們需要將API託管到合適的平臺上進行能力開放,優秀的平臺減少API提供者的工作量,抽取公共能力使API提供者更加專注於業務功能開發。華為雲的API閘道器集成了監控、流控、負載均衡等一系列功能,可以為開發者提供高效能、高可用的API 託管服務,實現個人、企業API能力的快速開放。
關於API閘道器的詳情,可以點選下面連結進行體驗: ofollow,noindex" target="_blank">https://console.huaweicloud.com/apig/?region=cn-north-1#/apig/expdemo