1. 什么是graphql
GraphQL 既是一種用于 API 的查詢語言也是一個滿足你數(shù)據(jù)查詢的運行時。直譯過來就是圖查詢語言,所以當(dāng)他在處理圖狀數(shù)據(jù)的時候,會有很大的優(yōu)勢。
2. graphql的優(yōu)勢
Ask for what you need 要什么點什么,參數(shù)不多不少剛剛好
只需一次請求,獲取多個資源
API演進過程,平滑無痕
3.舉個??
比如我們現(xiàn)在后端定義了一個用戶user模塊,以及一個針對user模塊的查詢Query,代碼大概如下:
type user {
telephone: String
QQ: String
id: ID!
name: String!
age: Float
hobby: [String]
}
type Query {
userQuery(id: String!): user!
}
這里可以看出graphql中實體的參數(shù)都是有類型、以及是否可為空的校驗。
然后Query和Mutation是graphql里面定義的操作關(guān)鍵字,用來表示查詢請求以及更新請求,在單個請求的情況下,兩者只有語義上的區(qū)別,但是在多個資源同時在一次請求中發(fā)起時,多個query會并行執(zhí)行,而Mutation則會根據(jù)順序依次執(zhí)行。
接下來我們再從前端發(fā)起一個請求,查詢某個用戶的信息,請求的參數(shù)形式大概如下
query userQuery($id: String!) {
user(id: $id) {
name
age
telephone
}
}
這是一個針對用戶user實體的請求,并且告訴接口,我只要知道name、age、telephone這三個信息,那么這次的請求成功后,接口就只會返回這三個參數(shù),不多也不少。
{
data: {
user: {
name: "張三",
age: 18,
telephone: "13012345678"
}
}
}
接下來如果,我們的接口要進行演進,需要新增的寵物信息的數(shù)據(jù),寵物信息與用戶相關(guān)聯(lián),但是單獨存放在另一個數(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!
}
只需要新增一個寵物的實體定義,并且把它放在user實體的下面相關(guān)聯(lián)。前端同時把需要查詢的寵物信息參數(shù),也加到請求中來,就可以請求得到寵物信息相關(guān)字段了。
query userQuery($id: String!) {
user(id: $id) {
name
age
telephone
pet {
name
species
}
}
}
接口的升級過程也是非常的平滑,并且多個資源的查詢在一次請求中就已經(jīng)完成了。同時之前只查詢用戶信息的情況也能繼續(xù)兼容,只需要在前端發(fā)起請求時去掉pet相關(guān)請求參數(shù)即可。
上面pet和user是有關(guān)聯(lián)關(guān)系的,如果有另一個與user無關(guān)聯(lián)的實體,也是可以合并到一次請求中查詢得到資源的:
query userQuery($id: String!) {
user(id: $id) {
name
age
telephone
pet {
name
species
}
}
activity {
id
name
createdTime
}
}
可以看到雖然graphql查詢的數(shù)據(jù)是圖狀結(jié)構(gòu)的,但是處理起來最后返回給前端的其實是樹狀結(jié)構(gòu)的數(shù)據(jù),每個查詢(query)或修改(mutation)返回的結(jié)構(gòu)始終有一個根節(jié)點,而且能看出節(jié)點之間由上而下的父子關(guān)系。
vs restful API
restful API中使用GET、PUT、POST等http方法來約定對資源的操作動作,graphql使用自己Query、Mutation來定義操作,使用post方法發(fā)起http請求,將查詢參數(shù)語句放在body之中。
restful API可使用http狀態(tài)碼來表示接口的異常錯誤,而graphql返回的http狀態(tài)碼始終是200,只有將錯誤信息錯誤碼再次封裝放在返回體中。
restful API可以使用swagger等工具來展示接口文檔,graphql中數(shù)據(jù)結(jié)構(gòu)schema即是接口文檔。
graphql不能使用http緩存,因為graphql的請求通常是http post方法。所以在graphql中要使用緩存,只有在客戶端集成,不過一般的graphql客戶端包(比如Apollo)都已集成了緩存功能。