在法國(guó)巴黎API日這上,Arnaud Lauret 談了GraphQL和RESTful HTTP API各自的優(yōu)點(diǎn)和缺點(diǎn)。從他的總結(jié)可以看出,是使用場(chǎng)景決定了具體該使用哪種API,而且這兩類(lèi)API在實(shí)際使用中會(huì)有很多的權(quán)衡考慮。
GraphQL是一種API查詢(xún)語(yǔ)言,是由Facebook創(chuàng)建并最終開(kāi)源的,可以認(rèn)為是REST的一種替代品。來(lái)自AXA Banque的API架構(gòu)師Lauret給出了一些可對(duì)二者進(jìn)行比較的切入點(diǎn):
GraphQL能夠通過(guò)一次查詢(xún)得到所有需要的數(shù)據(jù),從而減少網(wǎng)絡(luò)跳轉(zhuǎn)的次數(shù)。GraphQL采用所見(jiàn)即所得模型,這樣客戶端代碼不易出錯(cuò)。RESTful HTTP通過(guò)使用狀態(tài)碼和HTTP verb,提高了結(jié)果的一致性和可預(yù)測(cè)性。借助超媒體,在用戶使用API時(shí)可以“發(fā)現(xiàn)”資源間的關(guān)系,這簡(jiǎn)化了RESTful用戶的具體實(shí)現(xiàn)。HTTP實(shí)現(xiàn)了緩存機(jī)制而GraphQL還沒(méi)有實(shí)現(xiàn)。GraphQL給用戶提供了schema,這很有用,但是需要注意的是接口描述并非API文檔。Lauret認(rèn)為GraphQL的主要優(yōu)勢(shì)是其使用的所見(jiàn)即所得(WYSIWYG)模型。也就是說(shuō),查詢(xún)結(jié)果的結(jié)構(gòu)是查詢(xún)結(jié)構(gòu)本身的精確映射,這樣的話,用戶在解排(unmarshal)響應(yīng)的時(shí)候不容易出錯(cuò)。
他也解釋了為什么GraphQL模型可以減少網(wǎng)絡(luò)跳轉(zhuǎn)次數(shù)。對(duì)RESTful HTTP來(lái)說(shuō),資源和子資源可能存在于不同的節(jié)點(diǎn)上,所以需要多個(gè)請(qǐng)求才能獲取到期望的數(shù)據(jù)的情況就在所難免。但是GraphQL卻可以在單次請(qǐng)求中獲取到所有期望數(shù)據(jù)。實(shí)際上,一次只查詢(xún)系統(tǒng)中的一種資源是有可能的。
雖然Lauret認(rèn)為模型非常強(qiáng)大,但是他也解釋了單端點(diǎn)方案可能帶來(lái)的一致性和可預(yù)測(cè)性損失。相對(duì)于RESTful HTTP API,GraphQL不能正確使用HTTP verb會(huì)帶來(lái)很明顯的損失。舉個(gè)例子,在使用RESTful HTTP時(shí),當(dāng)用戶向資源發(fā)送了DELETE請(qǐng)求時(shí),用戶清楚這個(gè)操作是安全和冪等的,同時(shí)也清楚這個(gè)操作是用來(lái)刪除資源的。
Lauret指出GraphQL缺少HTTP狀態(tài)碼會(huì)帶來(lái)可預(yù)測(cè)性損失,HTTP狀態(tài)碼是人機(jī)都可讀的。相關(guān)的例子如當(dāng)不能找到資源時(shí)返回的404狀態(tài)碼,或者用戶沒(méi)有權(quán)限訪問(wèn)時(shí)返回403狀態(tài)碼等等。
REST充分利用了超媒體,也就是說(shuō)通過(guò)遍歷API,用戶就可以發(fā)現(xiàn)鏈接和相關(guān)資源。這就消除了用戶用于鏈接構(gòu)建和給客戶端返回資源關(guān)系等操作的需求。Lauret解釋說(shuō)因?yàn)镚raphQL完全聚焦于數(shù)據(jù),所以開(kāi)發(fā)者會(huì)更加依賴(lài)于文檔。
因?yàn)镠TTP緩存已經(jīng)是web架構(gòu)的一部分,所以Laure強(qiáng)調(diào)HTTP RESTful API使用了這種標(biāo)準(zhǔn)的HTTP緩存,而GraphQL的用戶則需要自己實(shí)現(xiàn)緩存機(jī)制, 這種額外的負(fù)擔(dān)其實(shí)是可以避免的。
Lauret列出了GraphQL的最后一個(gè)優(yōu)勢(shì),即提供schema,schema可以在運(yùn)行時(shí)被獲取到。當(dāng)客戶端決定可能的查詢(xún)時(shí),這非常有用。但是Lauret警告說(shuō)接口描述不是文檔,GraphQL不足以解決所有的API文檔問(wèn)題。
作為總結(jié),Lauret認(rèn)為沒(méi)有通用方案,只要是對(duì)當(dāng)前需求有利的方案都可以使用。他也提到,由于高級(jí)API所具有的共性,如果用戶不善于使用某種API,那么他們其實(shí)不善于使用任何一種API。完整視頻可以通過(guò)這里在線觀看,關(guān)于該演講的總結(jié)可以參考該篇博客文章。
查看英文原文:GraphQL vs REST: Things to Consider