1. 什么是graphql
GraphQL 既是一種用于 API 的查詢語(yǔ)言也是一個(gè)滿足你數(shù)據(jù)查詢的運(yùn)行時(shí)雌团。直譯過來就是圖查詢語(yǔ)言棍厂,所以當(dāng)他在處理圖狀數(shù)據(jù)的時(shí)候棕孙,會(huì)有很大的優(yōu)勢(shì)。
2. graphql的優(yōu)勢(shì)
Ask for what you need 要什么點(diǎn)什么脖律,參數(shù)不多不少剛剛好
只需一次請(qǐng)求谢肾,獲取多個(gè)資源
API演進(jìn)過程,平滑無痕
3.舉個(gè)??
比如我們現(xiàn)在后端定義了一個(gè)用戶user模塊小泉,以及一個(gè)針對(duì)user模塊的查詢Query芦疏,代碼大概如下:
type user {
telephone: String
QQ: String
id: ID!
name: String!
age: Float
hobby: [String]
}
type Query {
userQuery(id: String!): user!
}
這里可以看出graphql中實(shí)體的參數(shù)都是有類型、以及是否可為空的校驗(yàn)微姊。
然后Query和Mutation是graphql里面定義的操作關(guān)鍵字酸茴,用來表示查詢請(qǐng)求以及更新請(qǐng)求,在單個(gè)請(qǐng)求的情況下兢交,兩者只有語(yǔ)義上的區(qū)別弊决,但是在多個(gè)資源同時(shí)在一次請(qǐng)求中發(fā)起時(shí),多個(gè)query會(huì)并行執(zhí)行魁淳,而Mutation則會(huì)根據(jù)順序依次執(zhí)行。
接下來我們?cè)購(gòu)那岸税l(fā)起一個(gè)請(qǐng)求与倡,查詢某個(gè)用戶的信息界逛,請(qǐng)求的參數(shù)形式大概如下
query userQuery($id: String!) {
user(id: $id) {
name
age
telephone
}
}
這是一個(gè)針對(duì)用戶user實(shí)體的請(qǐng)求,并且告訴接口纺座,我只要知道name息拜、age、telephone這三個(gè)信息净响,那么這次的請(qǐng)求成功后少欺,接口就只會(huì)返回這三個(gè)參數(shù),不多也不少馋贤。
{
data: {
user: {
name: "張三",
age: 18,
telephone: "13012345678"
}
}
}
接下來如果赞别,我們的接口要進(jìn)行演進(jìn),需要新增的寵物信息的數(shù)據(jù)配乓,寵物信息與用戶相關(guān)聯(lián)仿滔,但是單獨(dú)存放在另一個(gè)數(shù)據(jù)表中。那么只需要將schema聲明改成這樣:
type user {
telephone: String
QQ: String
id: ID!
name: String!
age: Float
hobby: [String]
pet: [pet]
}
type pet {
name
temper
species
age
weight
}
type Query {
userQuery(id: String!): user!
}
只需要新增一個(gè)寵物的實(shí)體定義犹芹,并且把它放在user實(shí)體的下面相關(guān)聯(lián)崎页。前端同時(shí)把需要查詢的寵物信息參數(shù),也加到請(qǐng)求中來腰埂,就可以請(qǐng)求得到寵物信息相關(guān)字段了飒焦。
query userQuery($id: String!) {
user(id: $id) {
name
age
telephone
pet {
name
species
}
}
}
接口的升級(jí)過程也是非常的平滑,并且多個(gè)資源的查詢?cè)谝淮握?qǐng)求中就已經(jīng)完成了屿笼。同時(shí)之前只查詢用戶信息的情況也能繼續(xù)兼容牺荠,只需要在前端發(fā)起請(qǐng)求時(shí)去掉pet相關(guān)請(qǐng)求參數(shù)即可翁巍。
上面pet和user是有關(guān)聯(lián)關(guān)系的,如果有另一個(gè)與user無關(guān)聯(lián)的實(shí)體志电,也是可以合并到一次請(qǐng)求中查詢得到資源的:
query userQuery($id: String!) {
user(id: $id) {
name
age
telephone
pet {
name
species
}
}
activity {
id
name
createdTime
}
}
可以看到雖然graphql查詢的數(shù)據(jù)是圖狀結(jié)構(gòu)的曙咽,但是處理起來最后返回給前端的其實(shí)是樹狀結(jié)構(gòu)的數(shù)據(jù),每個(gè)查詢(query)或修改(mutation)返回的結(jié)構(gòu)始終有一個(gè)根節(jié)點(diǎn)挑辆,而且能看出節(jié)點(diǎn)之間由上而下的父子關(guān)系例朱。
vs restful API
restful API中使用GET、PUT鱼蝉、POST等http方法來約定對(duì)資源的操作動(dòng)作洒嗤,graphql使用自己Query、Mutation來定義操作魁亦,使用post方法發(fā)起http請(qǐng)求渔隶,將查詢參數(shù)語(yǔ)句放在body之中。
restful API可使用http狀態(tài)碼來表示接口的異常錯(cuò)誤洁奈,而graphql返回的http狀態(tài)碼始終是200间唉,只有將錯(cuò)誤信息錯(cuò)誤碼再次封裝放在返回體中。
restful API可以使用swagger等工具來展示接口文檔利术,graphql中數(shù)據(jù)結(jié)構(gòu)schema即是接口文檔呈野。
graphql不能使用http緩存,因?yàn)間raphql的請(qǐng)求通常是http post方法印叁。所以在graphql中要使用緩存被冒,只有在客戶端集成,不過一般的graphql客戶端包(比如Apollo)都已集成了緩存功能轮蜕。