GraphQL是什么
GraphQL是facebook開源的一套數(shù)據(jù)交互方案,它并非某種具體的語言或者框架,它只是提供了一套解決方案,這套解決方案通過GraphQL規(guī)范進行定義,不同語言可以有自己的GraphQL實現(xiàn),目前已經(jīng)有很多語言完成了GraphQL的實現(xiàn),可以在這里查看。
怎么使用GraphQL
GraphQL致力于提供一種直觀的彈性語法系統(tǒng),用以描述客戶端程序設(shè)計時的數(shù)據(jù)需求以及數(shù)據(jù)交互行為。通俗地講就是允許客戶端在請求中精確的定義自己需要什么,服務端根據(jù)客戶端的請求精確的返回相應的內(nèi)容。比如有如下兩個相互關(guān)聯(lián)的實體:
Teacher{
name: String
phone: String
age: Int
}
School{
id: String
name: String
address: String
teachers: List<Teacher>
}
使用GraphQL查詢指定學校的名稱是這樣的:
school(schoolId: "schoolId1"){
name
}
返回:
data{
"name" : "北京大學"
}
如果想要查詢學校的名稱以及所有老師的名字和電話:
school(schoolId: "schoolId1"){
name
teachers{
name
phone
}
}
將得到:
data{
"name" : "北京大學"
"teachers" : [
{
"name" : "李老師",
"phone" : "13312345678"
},
{
"name" : "張老師",
"phone" : "13312345673"
},
{
"name" : "王老師",
"phone" : "13312345672"
}
]
}
以上只演示了GraphQL提供的查詢(query)功能,GraphQL還支持修改(mutation)和訂閱(subscription)。
要使得客戶端可以使用GraphQL的方式請求數(shù)據(jù),首先需要在服務端提供GraphQL服務,這里可以查看現(xiàn)有的實現(xiàn)了GraphQL的平臺,關(guān)于如何搭建GraphQL的服務,請查看GraphQL(二):GraphQL服務搭建
同時,GraphQL提供了強大的開發(fā)者工具GraphiQL,可以實時查看數(shù)據(jù)模型和API,為前后端開發(fā)者提供了一個便捷的溝通平臺。
為什么要使用GraphQL
通過上面的內(nèi)容,大致可以了解GraphQL給前后端數(shù)據(jù)交互帶來的變化。
使用RESTful風格的API,會從指定接口加載數(shù)據(jù)。每個接口都明確定義了返回的數(shù)據(jù)結(jié)構(gòu)。這意味著客戶端需要的數(shù)據(jù),已經(jīng)在URL中制定好了。GraphQL中采用的方式截然不同,GraphQL的API通常只暴露一個接口,而不是返回固定數(shù)據(jù)結(jié)構(gòu)的多個接口。 GraphQL返回的數(shù)據(jù)結(jié)構(gòu)不是一成不變的,而是靈活的,讓客戶端來決定真正需要的是什么數(shù)據(jù)。
這樣的變化能夠在一定程度上解決使用RESTful風格接口完成數(shù)據(jù)交互時會遇到的問題:
-
多端點,每個API都有自己的路徑需要管理
image - API數(shù)量龐大,新人自學習困難
GraphQL通過圖的方式來組織模型,結(jié)合GraphiQL,新人能夠快速上手 - 后端數(shù)據(jù)模型難以規(guī)范
RESTful接口多為頁面驅(qū)動,后端可能會設(shè)計很多差別不大的模型,目前并沒有一種強約束去要求后端開發(fā)人員規(guī)范模型,GraphQL要求在一開始就完成業(yè)務模型的分析和定義,避免后面業(yè)務模型的泛濫 - 在API設(shè)計時往往是面向頁面的,而頁面相比模型具有更差的穩(wěn)定性
- API文檔維護工作量大
RESTful的API需要管理大量文檔,但是依然存在文檔更新、文檔查閱方便的問題,雖然可以動用人力完善工具去解決,但是GraphQL天然就自帶文檔工具特性。我們在定義字段時,一并寫上description,通過GraphiQL可以實時查看:
type School {
id: ID!
# 學校id
schoolId: String
# 學校名稱
schoolName: String
# 學校年齡
schoolAge: Int
# 學校地址
schoolAddress: String
# 學校包含的老師
teachers: [Teacher]
# 校長
master: String
}
GraphiQL中查看:

- 數(shù)據(jù)聚合較為麻煩
這是在后端經(jīng)常需要處理的問題,比如,客戶端需要一些數(shù)據(jù),我們定義了一個RESTful的接口,但是這些數(shù)據(jù)分別在A和B服務中,最終我們會在后臺手動聚合A和B的數(shù)據(jù)到一個模型里返回。而GraphQL通過不同的Resolver天然完成了數(shù)據(jù)聚合功能
GraphQL解除了接口和數(shù)據(jù)之間的綁定,對業(yè)務數(shù)據(jù)模型做了抽象和整理,以圖的方式來明確模型之間的關(guān)系,通過這些關(guān)系,具體業(yè)務場景可以定制自己的數(shù)據(jù),不同的業(yè)務場景只要基于同樣一套基礎(chǔ)數(shù)據(jù)模型就可以復用過往的接口。
以上好處講起來有些抽象,需要多多實踐多多體會。
