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