- Spring Boot進(jìn)階:原理、實(shí)戰(zhàn)與面試題分析
- 鄭天民
- 1635字
- 2022-07-05 09:41:54
4.3.1 GraphQL與RESTful API
假設(shè)正在開(kāi)發(fā)一個(gè)Web應(yīng)用程序,讓我們先來(lái)回想日常開(kāi)發(fā)過(guò)程中的真實(shí)場(chǎng)景:服務(wù)端開(kāi)發(fā)人員通過(guò)HTTP暴露了一個(gè)RESTful API,然后前端開(kāi)發(fā)人員嘗試對(duì)這個(gè)HTTP端點(diǎn)發(fā)起調(diào)用。這個(gè)HTTP端點(diǎn)一開(kāi)始如代碼清單4-56所示。
代碼清單4-56 普通HTTP端點(diǎn)示例代碼
請(qǐng)求: GET https://api.example.com/user/1 響應(yīng): { "id": "1", "name": "tianyalan", "age": "38", "address": "shanghai" }
看上去非常簡(jiǎn)單,對(duì)不對(duì)?剛開(kāi)始前后端聯(lián)調(diào)一切正常。不知什么時(shí)候,前端開(kāi)發(fā)人員發(fā)現(xiàn)響應(yīng)結(jié)果中原來(lái)的address字段不見(jiàn)了,而是出現(xiàn)了一個(gè)location字段,原來(lái)是后端開(kāi)發(fā)人員覺(jué)得address這個(gè)字段名不合適,偷偷把它改成了location,但并沒(méi)有告訴前端開(kāi)發(fā)人員。圖4-5展示了這一過(guò)程。這時(shí)候,前后端之間就需要重新明確API定義,并再一次進(jìn)行聯(lián)調(diào)。顯然,這個(gè)過(guò)程實(shí)際上是非常浪費(fèi)時(shí)間的。

圖4-5 Web API中字段名變更示意圖
相信你對(duì)上面這個(gè)場(chǎng)景非常熟悉,因?yàn)槲覀兛赡苊刻於荚诜磸?fù)經(jīng)歷著類似的場(chǎng)景。從這些場(chǎng)景中,前后端開(kāi)發(fā)人員已經(jīng)意識(shí)到,傳統(tǒng)的RESTful API并不能非常好地滿足前后端分離場(chǎng)景下的交互需求。我們可以進(jìn)一步把RESTful API存在的問(wèn)題做一些梳理。
1. RESTful API存在的問(wèn)題
RESTful API的第一個(gè)典型問(wèn)題就是前端無(wú)法預(yù)判響應(yīng)的數(shù)據(jù)格式,正如圖4-5所展示的那樣,一旦服務(wù)端對(duì)數(shù)據(jù)結(jié)構(gòu)做了任何改變,前端都只能被動(dòng)接收,而無(wú)法在發(fā)起請(qǐng)求之前感知到這種改變。
RESTful API的第二個(gè)典型問(wèn)題是無(wú)法根據(jù)請(qǐng)求控制對(duì)應(yīng)的返回結(jié)果。例如在圖4-5的場(chǎng)景中,前端請(qǐng)求可能只想獲取User對(duì)象中的name和age字段,而不需要address字段。顯然,RESTful API無(wú)法滿足這種訴求,除非另外開(kāi)發(fā)一個(gè)HTTP端點(diǎn)。我們知道,數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸是需要成本的,無(wú)法按需獲取數(shù)據(jù)同樣導(dǎo)致了資源的不必要浪費(fèi)。
RESTful API的第三個(gè)典型問(wèn)題就是多次請(qǐng)求。再次回到上述場(chǎng)景中,假設(shè)User對(duì)象中包含了一組家庭成員信息。那么基于RESTful API,如果想要獲取這些數(shù)據(jù),就只能再發(fā)起一個(gè)專門的請(qǐng)求來(lái)根據(jù)User的id獲取對(duì)應(yīng)的家庭成員列表,例如圖4-6中所展示的https://api.example.com/user/family/1。

圖4-6 RESTful API的多次請(qǐng)求示意圖
當(dāng)然,我們也可以針對(duì)該需求專門設(shè)計(jì)一個(gè)能夠同時(shí)返回用戶信息和家庭成員信息的接口。但這又會(huì)引出RESTful API的第四個(gè)典型問(wèn)題,即請(qǐng)求地址過(guò)多的問(wèn)題。如果針對(duì)各個(gè)具體場(chǎng)景我們都需要一一暴露專門的HTTP端點(diǎn),那么在一個(gè)系統(tǒng)中HTTP端點(diǎn)數(shù)量會(huì)非常龐大,難以維護(hù)和管理。
RESTful API的問(wèn)題已經(jīng)暴露得非常清楚了。如何有效解決這些問(wèn)題呢?可以引入一個(gè)新技術(shù),即GraphQL。
相比于REST,GraphQL可以說(shuō)是一個(gè)比較新的技術(shù),它于2012年誕生在Facebook內(nèi)部,并于2015年正式開(kāi)源。顧名思義,GraphQL是一種基于圖(Graph)的查詢語(yǔ)言(Query Language,QL),從根本上改變了前后端交互API的定義和實(shí)現(xiàn)方式。接下來(lái),我們?cè)敿?xì)分析如何通過(guò)GraphQL解決RESTful API所面臨的一系列問(wèn)題。
2. GraphQL的解決方案
要想使用GraphQL,我們首先需要關(guān)注它發(fā)送請(qǐng)求的方式。針對(duì)獲取用戶信息這個(gè)場(chǎng)景,一個(gè)典型的請(qǐng)求示例如代碼清單4-57所示。
代碼清單4-57 基于GraphQL的請(qǐng)求示例代碼
{ user (id: "1") { name age } }
可以看到基于GraphQL的請(qǐng)求方式與使用RESTful API有很大的不同。除了在請(qǐng)求體中指定了目標(biāo)User對(duì)象的參數(shù)id值之外,我們還額外指定了name和age這兩個(gè)參數(shù),也就是告訴服務(wù)器端這次請(qǐng)求所希望獲取的數(shù)據(jù)字段。
顯然,這種請(qǐng)求方式完美解決了RESTful API中無(wú)法根據(jù)請(qǐng)求控制對(duì)應(yīng)返回結(jié)果的問(wèn)題。同時(shí),這種請(qǐng)求方式也解決了前端無(wú)法預(yù)判響應(yīng)的數(shù)據(jù)的格式問(wèn)題,因?yàn)榍岸嗽谡?qǐng)求的同時(shí)已經(jīng)知道從服務(wù)端返回的數(shù)據(jù)字段就是請(qǐng)求中指定的字段,因此就不需要再對(duì)響應(yīng)結(jié)果進(jìn)行專門的判斷和處理。
針對(duì)RESTful API存在的多次請(qǐng)求問(wèn)題,GraphQL可以把多次請(qǐng)求合并成一次。例如,我們可以發(fā)送如代碼清單4-58所示的請(qǐng)求。
代碼清單4-58 基于GraphQL的合并多次請(qǐng)求示例代碼
{ users { name age members { name } } }
在該請(qǐng)求中,我們指定了想要獲取的User對(duì)象中的name和age字段,同時(shí)也指定了該獲取用戶對(duì)應(yīng)的家庭成員列表字段members以及它的子字段name。這樣,通過(guò)一次請(qǐng)求,我們就可以同時(shí)獲取用戶信息和家庭成員信息,而不需要像RESTful API那樣發(fā)送兩次請(qǐng)求。
講到這里,你可能已經(jīng)注意到,通過(guò)GraphQL發(fā)起請(qǐng)求實(shí)際上只需要指定一個(gè)HTTP端點(diǎn)地址即可,因?yàn)槲覀兛梢曰谕粋€(gè)端點(diǎn)傳入不同的參數(shù)而獲取不同的結(jié)果,也就不需要專門設(shè)計(jì)一批HTTP端點(diǎn)來(lái)分別處理不同的請(qǐng)求了。
總結(jié)一下,RESTful API所存在的核心問(wèn)題通過(guò)GraphQL都可以得到解決。
- 數(shù)據(jù)科學(xué)實(shí)戰(zhàn)手冊(cè)(R+Python)
- ClickHouse性能之巔:從架構(gòu)設(shè)計(jì)解讀性能之謎
- Design Principles for Process:driven Architectures Using Oracle BPM and SOA Suite 12c
- Delphi程序設(shè)計(jì)基礎(chǔ):教程、實(shí)驗(yàn)、習(xí)題
- Python入門很簡(jiǎn)單
- The React Workshop
- 新編Premiere Pro CC從入門到精通
- Android底層接口與驅(qū)動(dòng)開(kāi)發(fā)技術(shù)詳解
- RSpec Essentials
- Xcode 6 Essentials
- Python從入門到精通(第3版)
- 遠(yuǎn)方:兩位持續(xù)創(chuàng)業(yè)者的點(diǎn)滴思考
- Blender 3D Cookbook
- MySQL核心技術(shù)與最佳實(shí)踐
- Mastering Data Analysis with R