Google Cloud的API設(shè)計(jì)

來(lái)源: 知乎
作者:劉夢(mèng)馨
時(shí)間:2020-10-28
17408
最近(很久前)在設(shè)計(jì) API 接口的時(shí)候發(fā)現(xiàn)了一些很難取舍的地方,就看了下業(yè)界領(lǐng)先的企業(yè)都是怎么設(shè)計(jì)類(lèi)似 API 的,發(fā)現(xiàn)了很多之前設(shè)計(jì)的缺陷和一些新的思路。主要參考了 AWS 和 Google Cloud 的 API 設(shè)計(jì),兩家的設(shè)計(jì)可以說(shuō)是把兩個(gè)不同的風(fēng)格發(fā)揮到了極致,做同樣的事情 API 的各個(gè)方面都可以設(shè)計(jì)的完全不一樣。

christina-wocintechchat-com-EkeThvO9VfM-unsplash.jpg

最近(很久前)在設(shè)計(jì)API接口的時(shí)候發(fā)現(xiàn)了一些很難取舍的地方,就看了下業(yè)界領(lǐng)先的企業(yè)都是怎么設(shè)計(jì)類(lèi)似API的,發(fā)現(xiàn)了很多之前設(shè)計(jì)的缺陷和一些新的思路。主要參考了AWS和Google Cloud的API設(shè)計(jì),兩家的設(shè)計(jì)可以說(shuō)是把兩個(gè)不同的風(fēng)格發(fā)揮到了極致,做同樣的事情API的各個(gè)方面都可以設(shè)計(jì)的完全不一樣。Google有一個(gè)自己的API Design規(guī)范可以在網(wǎng)上找到,不過(guò)真實(shí)的GCE API規(guī)范略有一些出入。而AWS的API設(shè)計(jì)是沒(méi)有什么文檔的,只能通過(guò)現(xiàn)有的API進(jìn)行逆向工程來(lái)反推設(shè)計(jì)理念。這篇文章會(huì)比較瑣碎,更像是一個(gè)讀書(shū)筆記,細(xì)節(jié)的東西會(huì)比較多。

Google Cloud API

由于Google的文檔比較詳細(xì)了,就先照著Google的文檔來(lái)講,而Google的API是按照REST風(fēng)格來(lái)的,而REST只是一種紙面的模式,每家的實(shí)現(xiàn)可能都不一樣,我們就來(lái)看下Google眼里的REST是什么樣的。然后介紹一下REST API的一些局限和缺點(diǎn)以及Google的解決方式。

最權(quán)威的REST當(dāng)然還是得去看論文了,不過(guò)對(duì)于普通開(kāi)發(fā)者來(lái)講HTTP的REST就是一個(gè)URL指向一個(gè)資源,然后這個(gè)URL上通過(guò)不同的HTTP方法來(lái)實(shí)現(xiàn)對(duì)這個(gè)資源的不同操作。簡(jiǎn)單來(lái)說(shuō)就是指向資源的URL+HTTP方法就構(gòu)成了常見(jiàn)的REST API。這里面每一個(gè)部分都有很多門(mén)道。

URL

URL可以分成好幾個(gè)組成部分

1.域名,不同的域名可以區(qū)分這個(gè)網(wǎng)站提供的不同API服務(wù)。比如一個(gè)圖書(shū),一個(gè)電影,域名就應(yīng)該是http://library.oilbeater.cn和http://moive.oilbeater.cn

2.版本號(hào),對(duì)應(yīng)不同的歷史版本,可以是v1,v2,也可以是alpha,beta這樣

3.資源集合,書(shū)店里可能會(huì)有多種資源的集合,比如圖書(shū),報(bào)紙,影碟,這就需要用資源集合來(lái)區(qū)分/books,/newspapers,/cds等等

4.資源名稱(chēng),這時(shí)候才真正到具體的資源,一個(gè)圖書(shū)可能就是http://library.oilbeater.com/v1/books/book_1

5.子資源,有時(shí)候一層的資源模型不能滿足現(xiàn)實(shí)的需求,比如圖書(shū)館的檢索是按照書(shū)架來(lái)的,需要先知道在哪個(gè)書(shū)架才能找到書(shū),就需要在中間插一層資源。最后的url可能就變成了http://library.oilbeater.com/v1/shelves/shelf_1/books/book_1

6.重復(fù)3-4

資源命名

1.資源名必須是合法的C語(yǔ)言變量名,這個(gè)規(guī)范主要是為了代碼和SDK的一致性,不然有個(gè)減號(hào)這樣的字符很多語(yǔ)言的SDK里這個(gè)資源對(duì)象你就不得不換個(gè)名字或者寫(xiě)法了,很容易造成不一致,一些自動(dòng)生成SDK的工具也會(huì)失敗

2.資源集合必須是復(fù)數(shù)

3.不要用縮寫(xiě)避免不必要的歧義

4.不要用過(guò)于泛化的資源類(lèi)型,像type,object,element,resource這樣的命名一來(lái)不是很清楚,二來(lái)很容易和編程語(yǔ)言的關(guān)鍵字撞名字,人為增加編程難度。方法

常用的HTTP方法有GET,POST,PUT,DELETE稍微常見(jiàn)的還有HEAD,PATCH,不太常見(jiàn)的還有COPY,LINK,LOCK,VIEW等等。由于HTTP是純文本的協(xié)議,并沒(méi)有規(guī)定只能用哪幾個(gè)方法,只要服務(wù)端做處理就可以自己再自定義其他方法的,比如Google自己就實(shí)現(xiàn)了一個(gè)BATCH來(lái)做批量處理。

每個(gè)HTTP方法和以對(duì)應(yīng)不同的語(yǔ)義,而且這些語(yǔ)義像GET是獲取,POST創(chuàng)建PUT更新DELETE刪除基本上大家都是形成共識(shí)的,API最后的統(tǒng)一性會(huì)很好。REST的初衷也是讓資源盡可能的多,每個(gè)資源的方法盡可能的只有標(biāo)準(zhǔn)的幾個(gè)方法,這樣所有的API看起來(lái)長(zhǎng)得都很像,學(xué)習(xí)和實(shí)現(xiàn)的成本都會(huì)很低。下面說(shuō)一下具體的每個(gè)方法需要注意的一些事情

List

1.需要用GET方法url指向資源集合,并返回資源的列表

2.List返回的內(nèi)容最好有分頁(yè)信息,而不是簡(jiǎn)單的一個(gè)資源列表,便于前端的展示并減少每次拿所有數(shù)據(jù)的性能消耗

3.資源列表需要是有序的,如果兩次請(qǐng)求同樣資源順序完全不一樣前端再不處理就會(huì)有奇奇怪怪的現(xiàn)象

4.List需要提供簡(jiǎn)單的按照某個(gè)字段排序,filter方法,更復(fù)雜的過(guò)濾查詢需要單獨(dú)的方法

5.可以返回一些metadata,比如資源數(shù)量,資源集合的信息等

Create

1.POST方法URL指向資源集合,創(chuàng)建成功需要返回這個(gè)資源,而不是只有一個(gè)201的狀態(tài)碼

2.需要允許client自己指定resource_id,而不是全部由系統(tǒng)自動(dòng)生成。這樣第三方系統(tǒng)可以根據(jù)情況進(jìn)行重試和重復(fù)檢查。不然一個(gè)create請(qǐng)求中間路徑上有重試就會(huì)生成多個(gè)id不同的資源,后續(xù)處理會(huì)很麻煩。

Update

1.PUT或者PATCH方法URL指向具體資源,更新成功需要返回資源實(shí)體

2.PUT一般用于整個(gè)資源實(shí)體的更新,而PATCH只更新某個(gè)字段。對(duì)于一個(gè)復(fù)雜的有大量字段的資源,最好兩種API都提供,而不是只提供一個(gè)PUT。只提供一個(gè)PUT即使只更新一個(gè)字段也需要傳遞完整的資源實(shí)體,很多情況下是沒(méi)必要的

用戶自定義方法

由于HTTP的標(biāo)準(zhǔn)方法是有限的,而很多語(yǔ)義是標(biāo)準(zhǔn)方法不能表示的,比如需要把書(shū)從一個(gè)書(shū)架移動(dòng)到另一個(gè)書(shū)架就很難用標(biāo)準(zhǔn)方法表示,這就需要用戶自定義方法。定義HTTP方法理論上沒(méi)問(wèn)題,但很多第三方庫(kù)并不支持這種方法,這種API給別人看也會(huì)比較奇怪,所以通常會(huì)把方法加在url里,通常是加在資源名稱(chēng)后面。比如移動(dòng)一本書(shū)就可以是/books/book_1:move

1.通常的做法是用『/』來(lái)做URL的分隔,但是在Google的規(guī)范里用的是用『:』因?yàn)?分隔會(huì)有歧義,不知道后面的到底是一個(gè)子資源還是一個(gè)用戶自定義方法。聽(tīng)起來(lái)很有道理的樣子,但是在GCE的API里并沒(méi)這么做也是用的『/』

2.盡管URL里有了自定義方法,HTTP方法還是盡量用符合語(yǔ)義的,比如更新類(lèi)的操作都用PUT

3.現(xiàn)實(shí)中很多操作都是標(biāo)準(zhǔn)HTTP方法表示起來(lái)很苦難的,比如重啟機(jī)器,發(fā)送郵件,賬號(hào)登錄這些,可以想一下這些操作如何用HTTP標(biāo)準(zhǔn)方法來(lái)設(shè)計(jì)API

標(biāo)準(zhǔn)字段

不同的資源有許多共同的屬性字段,由于每個(gè)資源對(duì)應(yīng)的API可能是由不同人在不同時(shí)間完成的,所以需要有個(gè)約定好的公共字段的命名,不然到最后會(huì)出現(xiàn)混亂的情況。比如資源需要有個(gè)id表示,就會(huì)出現(xiàn)不同資源有的叫uuid,有的叫id,有的叫resource_id;創(chuàng)建時(shí)間又有created_at,created_datetime,created_time,分頁(yè)又有page_token,next_page,page_num諸如此類(lèi)不一致的情況。同樣一些字段的類(lèi)型也需要統(tǒng)一,比如時(shí)間使用時(shí)間戳還是標(biāo)準(zhǔn)時(shí)間,帶不帶時(shí)區(qū)。

除了正常的返回就是錯(cuò)誤返回也要有統(tǒng)一的格式。錯(cuò)誤信息需要包含error_code,error_message和error_detail。其中error_message是用來(lái)返回給最終用戶的,而error_detail則用于內(nèi)部人源進(jìn)行錯(cuò)誤排查。

REST的缺陷

盡管REST API的設(shè)計(jì)原則在現(xiàn)實(shí)中使用的很廣,但是這種設(shè)計(jì)也是有很多局限性的。

1.層級(jí)設(shè)計(jì)很容易過(guò)多,比如在公有IAAS中需要獲得一private_ip的信息,這個(gè)ip可能是屬于某塊網(wǎng)卡的,網(wǎng)卡屬于某個(gè)機(jī)器,機(jī)器屬于某個(gè)subnet,subnet屬于某個(gè)vpc,vpc屬于某個(gè)region。設(shè)計(jì)出來(lái)的api就變成了/regions/region_id/vpcs/vpc_id/subnets/subnet_id/instances/instance_id/nics/nics_id/private_ips/private_ip_id這種API直接上就會(huì)覺(jué)得不合理。而且仔細(xì)考慮機(jī)器是不是應(yīng)該屬于subnet,private_ip是不是應(yīng)該直接是subnet的子資源,會(huì)有很多需要考慮的地方。

2.標(biāo)準(zhǔn)HTTP方法大多是操縱整個(gè)資源,而這個(gè)粒度在一些情況下太粗了。比如同樣是更新一個(gè)主機(jī)的操作,更新主機(jī)的一個(gè)tag和更新主機(jī)的name都是PUT一個(gè)資源實(shí)例url,而更改安全組將主機(jī)狀態(tài)設(shè)置成停止也是同樣的PUT方法和url就會(huì)有些不合理。盡管都是更新操作,但是更新的字段不同,功能不同,重要性也不同,用同樣的大PUT就會(huì)不合適。而且這些字段可能會(huì)對(duì)應(yīng)著不同的權(quán)限操作,如果任何更新都是同樣的方法,之后細(xì)粒度的權(quán)限控制也會(huì)變得十分痛苦。

3.涉及多資源的操作會(huì)很難設(shè)計(jì)。REST的思想是對(duì)資源進(jìn)行操作,但現(xiàn)實(shí)中一個(gè)操作可能會(huì)對(duì)應(yīng)多個(gè)資源,這時(shí)候?qū)τ诙鄠€(gè)不同資源關(guān)系的操作REST設(shè)計(jì)起來(lái)就比較頭疼了。比如給一個(gè)主機(jī)加一個(gè)eip,那么這個(gè)操作肯定要用到自定義方法了,接下來(lái)的問(wèn)題就是這個(gè)方法到底是屬于主機(jī)的,還是屬于eip的還是兩個(gè)資源都需要加一個(gè)同樣的方法?而且API的設(shè)計(jì)也會(huì)影響實(shí)現(xiàn)的思路,在設(shè)計(jì)時(shí)API是把主機(jī)和eip當(dāng)成獨(dú)立的資源,那么實(shí)現(xiàn)的時(shí)候很可能就忽略了他們倆之間是有關(guān)聯(lián)關(guān)系的,很可能到最后就會(huì)出問(wèn)題。

4.批量操作變得困難。由于REST API的更新和刪除url路徑都是指向具體一個(gè)資源的,批量的更新刪除就需要額外進(jìn)行設(shè)計(jì)。比如批量關(guān)閉幾個(gè)主機(jī),API的樣子就會(huì)和其他的完全不一樣。如果不設(shè)計(jì)批量操作的API只是組合使用單個(gè)資源的API,當(dāng)需要操作的實(shí)例多的時(shí)候很容易出現(xiàn)性能問(wèn)題,而且如果操作時(shí)間過(guò)長(zhǎng),那么中間各種沖突,不一致的幾率就會(huì)大幅上升。

Google的應(yīng)對(duì)方案

1.層級(jí)多的問(wèn)題,翻一下google cloud的api可以發(fā)現(xiàn)大部分的api url只有三層,前兩層還都是project和zone,一個(gè)實(shí)例的url就是/v1/projects/project/zones/zone/instances/instance換句話說(shuō)就是真正到了云里面的資源就沒(méi)有再分層了,所有的資源層級(jí)都是扁平的在同等地位,所有的資源都是關(guān)聯(lián)關(guān)系而不是層級(jí)關(guān)系。這樣就避免了層級(jí)過(guò)深和考慮如何設(shè)計(jì)層級(jí)的問(wèn)題,也保證了將來(lái)每個(gè)資源操作的靈活性。

2.大量的自定義方法。盡管REST本來(lái)的目的是大量的資源少量的標(biāo)準(zhǔn)操作,很顯然這個(gè)顯示環(huán)境中是有困難的。Google在instance這個(gè)資源的自定義方法就有20多種,最后的情況就是大量的資源加上幾個(gè)標(biāo)準(zhǔn)方法再加上大量的自定義方法。通過(guò)自定義方法,每個(gè)方法對(duì)應(yīng)一個(gè)操作,權(quán)限控制也可以對(duì)應(yīng)到每一個(gè)方法上,細(xì)粒度的權(quán)限控制也就可以實(shí)現(xiàn)。

3.HTTP BATCH方法。至于批量操作的問(wèn)題Google是通過(guò)自定義HTTP方法實(shí)現(xiàn)的,之前說(shuō)過(guò)了不要用自定義HTTP方法因?yàn)榇蠹也恢С?,可是Google這種能對(duì)Web標(biāo)準(zhǔn)起到影響的企業(yè)就任性了。BATCH方法其實(shí)就是在HTTP的body里再封裝多個(gè)標(biāo)準(zhǔn)的HTTP方法求情。這樣批量操作還是一個(gè)個(gè)的操作,不過(guò)可以一次性打包發(fā)過(guò)去不用一個(gè)個(gè)發(fā)送了。API也不用單獨(dú)再設(shè)計(jì)一套批量的,還能組合不同類(lèi)型的操作,不過(guò)一般企業(yè)就不要學(xué)這種作風(fēng)了。

盡管Google很詳細(xì)的做了API設(shè)計(jì)的文檔,但是如果你去看國(guó)內(nèi)IaaS廠商的API文檔會(huì)發(fā)現(xiàn)沒(méi)有一家是這么做的,甚至連一點(diǎn)REST的模樣都沒(méi)有。Google的API設(shè)計(jì)看上去最符合開(kāi)發(fā)者的常規(guī)思維,在這個(gè)領(lǐng)域反而顯得和一個(gè)另類(lèi)一樣,為啥子呢?如果你看過(guò)AWS的API就會(huì)發(fā)現(xiàn)國(guó)內(nèi)這些廠商大概都是從AWS那邊借(chao)鑒(xi)過(guò)來(lái)的。至于AWS是如何應(yīng)對(duì)REST世界中的類(lèi)似問(wèn)題以及他到底長(zhǎng)什么樣子,可能下篇會(huì)寫(xiě)。

立即登錄,閱讀全文
版權(quán)說(shuō)明:
本文內(nèi)容來(lái)自于知乎,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀點(diǎn),不代表快出海對(duì)觀點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
相關(guān)文章
新版GKE可管理最多6.5萬(wàn)集群節(jié)點(diǎn),超越AWS、Azure 10倍
新版GKE可管理最多6.5萬(wàn)集群節(jié)點(diǎn),超越AWS、Azure 10倍
Google Cloud公布最新Google Kubernetes Engine版本,號(hào)稱(chēng)可支持最高達(dá)65,000個(gè)節(jié)點(diǎn)的服務(wù)器集群,以執(zhí)行超大型AI模型。
Google Cloud
云服務(wù)
云計(jì)算
2024-11-152024-11-15
Google Cloud細(xì)說(shuō)AI變現(xiàn)途徑:用戶一年暴增10倍
Google Cloud細(xì)說(shuō)AI變現(xiàn)途徑:用戶一年暴增10倍
Google云計(jì)算平臺(tái)(Google Cloud)首席執(zhí)行官Thomas Kurian在高盛舉行的會(huì)議上,說(shuō)明了該公司究竟是通過(guò)哪些途徑將AI變現(xiàn)。
Google Cloud
谷歌云
云計(jì)算
2024-09-132024-09-13
云計(jì)算平臺(tái)GCP的服務(wù)存在權(quán)限提升漏洞,未經(jīng)授權(quán)的攻擊者可借此訪問(wèn)敏感數(shù)據(jù)
云計(jì)算平臺(tái)GCP的服務(wù)存在權(quán)限提升漏洞,未經(jīng)授權(quán)的攻擊者可借此訪問(wèn)敏感數(shù)據(jù)
7月24日安全企業(yè)Tenable披露影響Google Cloud Platform(GCP)的權(quán)限提升漏洞ConfusedFunction,這項(xiàng)弱點(diǎn)發(fā)生在名為Cloud Functions的無(wú)服務(wù)器運(yùn)算服務(wù),以及稱(chēng)作Cloud Build的CICD渠道服務(wù)。
Google Cloud
谷歌云
云計(jì)算
2024-07-272024-07-27
Gemini為核心,Google云計(jì)算AI戰(zhàn)略聚焦云服務(wù)和生產(chǎn)力GAI
Gemini為核心,Google云計(jì)算AI戰(zhàn)略聚焦云服務(wù)和生產(chǎn)力GAI
過(guò)去一年,企業(yè)GAI應(yīng)用的風(fēng)潮席卷全球,成了三大公有云積極搶攻的新戰(zhàn)場(chǎng),微軟靠著OpenAI助攻,去年在這場(chǎng)云計(jì)算GAI大戰(zhàn)中取得先機(jī),而Google后來(lái)居上,靠著自家PaLM模型和GAI生產(chǎn)力工具來(lái)迎戰(zhàn),AWS則是到去年底年會(huì)上,對(duì)于企業(yè)GAI應(yīng)用布局才有比較完整的布局與披露。
Google Cloud
谷歌云
云計(jì)算
2024-05-042024-05-04
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪
投稿采訪
出海管家
出海管家