
API貨幣化的最佳實(shí)踐:定價(jià)、打包和計(jì)費(fèi)
這就是我最初接觸 OpenAPI 或 API Blueprint 等 API 描述文檔的方式,也是我們的第一本書建議 API 開發(fā)人員做事的方式。這在當(dāng)時(shí)可能很有道理,但我很快發(fā)現(xiàn)這是一種不成熟的工作流程。
這里的一個(gè)問題是,“先寫代碼,后寫文檔”將 API 描述視為一種制作 API 參考文檔的奇特方式,而這只是 API 描述可以做的 100 件事之一。API 描述是機(jī)器可讀的文件,包含大量數(shù)據(jù)和元數(shù)據(jù),可用于在早期階段收集反饋,以便在通過模擬編寫 API 之前提高 API 的質(zhì)量,提供客戶端驗(yàn)證和服務(wù)器端驗(yàn)證。
首先編寫一堆代碼,部署東西,讓客戶上手并得到特別的親自動(dòng)手處理等,這是一項(xiàng)非常繁重的工作。當(dāng)整個(gè)階段完成后,花一個(gè)月的時(shí)間編寫“只會(huì)過時(shí)”的文檔,感覺就像是一項(xiàng)艱巨的任務(wù),大多數(shù)企業(yè)都很難優(yōu)先考慮,所以這項(xiàng)任務(wù)永遠(yuǎn)都做不完。
這是我經(jīng)常聽到的借口,說明為什么 WeWork 在 2016 年擁有約 50 名工程師,卻在任何時(shí)候都無法提供任何文檔,卻成功構(gòu)建了約 30 個(gè) API。缺乏文檔導(dǎo)致了我所見過的最瘋狂的時(shí)間和金錢浪費(fèi),人們構(gòu)建了新版本的端點(diǎn)和 API,因?yàn)闆]有人記得代碼是如何工作的。由于 API A 動(dòng)態(tài)返回來自 API B 和 API C 的 JSON 塊,而沒有任何序列化器,因此甚至幾乎不可能閱讀代碼。
“我們稍后再寫文檔”意味著“我們不會(huì)寫文檔”,等你發(fā)現(xiàn)需要它時(shí),已經(jīng)太晚了。如果你是少數(shù)幾個(gè)能快速完成的人之一,那么讓這些文檔與代碼“同步”是大多數(shù)開發(fā)人員面臨的最大問題。在我關(guān)于這個(gè)主題的API the Docs演講中,當(dāng)我問“這里有誰在努力保持代碼和文檔同步”時(shí),整個(gè)房間大約 80-100 人都舉起了手。
有幾種方法,但即使你完全使用Dredd或類似的工具來保持同步,還有另一個(gè)我們尚未涉及的相當(dāng)大的問題:你在給客戶機(jī)會(huì)使用它之前就構(gòu)建了整個(gè) API。
模擬經(jīng)常被忽視,人們浪費(fèi)時(shí)間和金錢構(gòu)建無意義的 API,而這些 API 對(duì)客戶沒有幫助。這通常意味著 v2 在 v1 之后很快推出,也許需要 v3,因?yàn)闀?huì)有更多客戶參與并提供更多反饋。這通常意味著 API 過于規(guī)范化,導(dǎo)致客戶需要發(fā)出 150 個(gè) HTTP 請(qǐng)求來解決他們的用例,或者資源非常龐大,這意味著在 100 個(gè)用戶不需要的字段中隱藏著有用的數(shù)據(jù)。
無論您為 API 構(gòu)建選擇了哪種 API 范式,用例驅(qū)動(dòng)的 API通常都比數(shù)據(jù)驅(qū)動(dòng)的 API 更有用。讓您的用戶盡早分享他們的反饋,因?yàn)榇藭r(shí)更改仍然成本低且容易,而不是在已經(jīng)投入生產(chǎn)并且更改變得更加復(fù)雜時(shí)。
這種對(duì) API 描述采用代碼優(yōu)先方法的流行變體是為了加快“稍后編寫文檔”部分的流程,許多 API 開發(fā)人員決定使用注釋或代碼注釋以特殊格式在其源代碼中散布 API 描述的片段。
有多種工具可用于此目的。在一些嚴(yán)格類型語言中,注釋工具包含的信息非常少,大多只有人類可讀的描述。可以從代碼中推斷出基本類型(“字符串”和“整數(shù)”)等信息,是否允許為空等。可悲的是,有些人認(rèn)為這就是他們需要放入描述文檔的所有信息。他們忽略了示例值、“電子郵件”或“日期時(shí)間”等格式(可以增加驗(yàn)證優(yōu)勢(shì)并使文檔更有用),以及 OpenAPI 或 JSON Schema 中的其他更高級(jí)的功能,如 allOf、oneOf 等。
以注釋為首要功能的語言通常對(duì)此支持得更好一些,例如 Java。它們擁有大量的注釋系統(tǒng),如果您在其中編寫了垃圾內(nèi)容,則可能會(huì)出現(xiàn)語法錯(cuò)誤。
class UserController {
@OpenApi(
path = "/users",
method = HttpMethod.POST,
// ...
)
public static void createUser(Context ctx) {
// ...
}
}
其他語言(例如 PHP)依賴于文檔塊注釋,而這只是在文本編輯器中寫入無意義的內(nèi)容。
/**
* @OAGet(path="/2.0/users/{username}",
* operationId="getUserByName",
* @OAParameter(name="username",
* in="path",
* required=true,
* description=Explaining all about the username parameter
* @OASchema(type="string")
* ),
* @OAResponse(response="200",
* description="The User",
* @OAJsonContent(ref="#/components/schemas/user"),
* @OALink(link="userRepositories", ref="#/components/links/UserRepositories")
* )
* )
*/
public function getUserByName($username, $newparam)
{
}
在我看來,這似乎很粗糙,但人們?yōu)樗q護(hù)的理由如下:“在代碼附近添加注釋意味著開發(fā)人員更有可能保持代碼更新”。更有可能并不一定。
使用注釋時(shí),您仍然需要使用其中一種方法來確保代碼和描述同步,但您必須添加構(gòu)建步驟以從源代碼導(dǎo)出,然后通過 Dredd 或類似程序運(yùn)行生成的 OpenAPI 文件。或者,您只能希望所有開發(fā)人員都記住并且“一切都會(huì)好起來”。
這里的反饋循環(huán)仍然有點(diǎn)長(zhǎng)。它是在你編寫了一大堆代碼之后出現(xiàn)的,或者你可能將所有路由都寫到了一堆空控制器中,并且可以導(dǎo)出 OpenAPI 來創(chuàng)建模擬服務(wù)器,但這一切聽起來仍然很繁重。還有更多改進(jìn)要做。
總體而言,“API 設(shè)計(jì)優(yōu)先”是指實(shí)質(zhì)上關(guān)閉反饋循環(huán)。在編寫任何代碼之前,您都會(huì)獲得模擬和文檔,因此在相當(dāng)多的客戶確認(rèn)界面符合他們的需求之前,您無需再對(duì)代碼進(jìn)行任何修改,而且由于您已經(jīng)擁有生成文檔所需的一切,因此您不必?fù)?dān)心以后再做這件事。
這種設(shè)計(jì)優(yōu)先的特定風(fēng)格仍然存在很多問題,但最近 API 領(lǐng)域的一些大人物一直在提倡這種做法。我認(rèn)為他們提倡這種做法主要是因?yàn)樗麄儏捑肓耸謱?API 描述:在這里插入關(guān)于“數(shù)千行 YAML”的常見抱怨。也許他們一開始使用 DSL 來設(shè)計(jì)東西,然后在完成后切換到注釋,再次希望這樣“它更有可能保持最新”。
這里的眾多錯(cuò)誤觀點(diǎn)之一是,認(rèn)為有一個(gè)設(shè)計(jì)階段,然后你就停止設(shè)計(jì),然后是代碼編寫的時(shí)間,之后我們不需要設(shè)計(jì)新的功能。
無論開發(fā)人員是手工編寫 API 代碼還是根據(jù) API 描述生成代碼,設(shè)計(jì)階段都是永無止境的。設(shè)計(jì)是一個(gè)循環(huán)的生命周期,具有反饋循環(huán),可產(chǎn)生新的資源和端點(diǎn)、新的全局版本或只是新的屬性。API 會(huì)隨著時(shí)間的推移而發(fā)展,在不收集客戶反饋的情況下推出新功能始終是一個(gè)壞主意,不僅僅是在初始設(shè)計(jì)階段。
我在Meetup上看到一些人使用“不可變服務(wù)”取得了成功,他們從 OpenAPI 生成路由、控制器、數(shù)據(jù)模型、docker 配置,甚至所有 Kubernetes 設(shè)置,然后他們只需在空白處插入一些業(yè)務(wù)邏輯并點(diǎn)擊部署即可。當(dāng)他們需要更改合同時(shí)會(huì)發(fā)生什么?那將是一項(xiàng)全新的服務(wù)。不允許更改。計(jì)劃得足夠好,你不需要花很長(zhǎng)時(shí)間調(diào)整它們,然后在需要更改時(shí)棄用并替換它們。不可變服務(wù)不是一種常見的做事方式,需要大量的紀(jì)律才能做好。
對(duì)于其他所有人來說,演變更為常見,因?yàn)榧词谷藗優(yōu)槠?API 使用主要的全球版本,也會(huì)在過程中做出向后兼容的更改(新端點(diǎn)等)。要求您“導(dǎo)入”O(jiān)penAPI,然后從那里繼續(xù)的工具會(huì)讓您在未來無法設(shè)計(jì)新功能,即使他們提供了導(dǎo)出 OpenAPI 功能(許多人沒有)。
更糟糕的是,許多此類工具都會(huì)在云中保留其自己的 API 描述版本,而這些版本可以獨(dú)立于 Git 存儲(chǔ)庫(kù)中的 API 描述進(jìn)行更改,這意味著您沒有真相來源:您有兩個(gè)謊言來源。
讓我們看一個(gè)工作流程,它允許您使用 API 描述作為單一事實(shí)來源,它會(huì)隨著您的代碼一起發(fā)展。
這種方法不再將 API 描述文檔視為事后的想法或苦差事,因?yàn)樗鼈儾皇恰_^去可能需要 DSL 才能使編寫 OpenAPI 變得容易,但有了Stoplight Studio等令人驚嘆的可視化編輯器,使用 DSL 來避免手動(dòng)編寫 YAML 的日子已經(jīng)一去不復(fù)返了。Studio 可讓您在本地機(jī)器上免費(fèi)使用 OpenAPI 文件,因此任何人都可以輕松構(gòu)建強(qiáng)大的描述文檔,甚至可以輕松地在多個(gè) API 之間重用模型,這樣整個(gè)“千行 YAML”的事情就完全消失了。
無論您使用 Studio、DSL 還是手寫,都請(qǐng)從空的存儲(chǔ)庫(kù)開始,只使用描述文檔。盡早并經(jīng)常運(yùn)行模擬服務(wù)器,獲取客戶的反饋,然后在達(dá)成一致后提交文檔。
然后您就可以開始編寫代碼了。使用描述文檔來支持服務(wù)器端驗(yàn)證甚至 API 網(wǎng)關(guān)驗(yàn)證的工具可以大大簡(jiǎn)化您需要編寫的代碼量。
這不是代碼生成,而是使用 API 描述來支持生產(chǎn)驗(yàn)證。您用于呈現(xiàn)文檔的相同描述文檔現(xiàn)在支持 API 的最復(fù)雜方面,并且事情永遠(yuǎn)不會(huì)“不同步”,因?yàn)橹挥幸粋€(gè)事實(shí)來源。
當(dāng)客戶請(qǐng)求新功能時(shí),您可以輕松添加新端點(diǎn)、引入新屬性等,并在開始編寫代碼之前獲得有關(guān)新內(nèi)容的反饋。您永遠(yuǎn)不會(huì)失去這種能力,因此您可以從先設(shè)計(jì)、再設(shè)計(jì)、再設(shè)計(jì)中受益。
這無助于保持響應(yīng)“同步”,但是由于您的描述文檔就在您的存儲(chǔ)庫(kù)中,因此您可以使用它們來大大簡(jiǎn)化您的單元/集成測(cè)試,從而覆蓋整個(gè)界面。
不要草率地編寫描述文檔。使用它們來規(guī)劃一些了不起的事情,并減少后續(xù)需要重新編碼的工作量。創(chuàng)建使用壽命更長(zhǎng)、文檔更完善、測(cè)試更充分的 API,同時(shí)減少開發(fā) API 所花費(fèi)的總時(shí)間。
文章轉(zhuǎn)載自:API設(shè)計(jì)優(yōu)化與代碼優(yōu)化
API貨幣化的最佳實(shí)踐:定價(jià)、打包和計(jì)費(fèi)
應(yīng)用程序開發(fā)中不可或缺的開放API
開發(fā)者生產(chǎn)力提升的API終極指南
制定藍(lán)圖:什么樣的API策略能夠確保未來的成功?
詳解API:應(yīng)用程序編程接口終極指南
精通API規(guī)范:構(gòu)建明確指導(dǎo)和預(yù)期的指南
API 優(yōu)先方法如何徹底改變軟件開發(fā)
掌握良好的 API 設(shè)計(jì)原則:是什么、為什么和怎么辦
API-first產(chǎn)品經(jīng)理的熱門 API 工具和 API 指標(biāo)
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)