是什么讓我放棄了Restful API?
點擊上方[全棧開發(fā)者社區(qū)]→右上角[...]→[設(shè)為星標(biāo)?]

背景


濫用REST接口,導(dǎo)致大量相似度很高(具有重復(fù)性)的API越來越冗余。
對于前端而言:REST API粒度較粗,難以一次性符合前端的數(shù)據(jù)要求,前端需要分多次請求接口數(shù)據(jù)。增加了前端人員的工作量。
對于后端而言:前端需要的數(shù)據(jù)往往在不同的地方具有相似性,但卻又不同,比如針對同樣的用戶信息,有的地方只需要用戶簡要信息(比如頭像、昵稱),有些地方需要詳細(xì)的信息,這就需要開發(fā)不同的接口來滿足這些需求。當(dāng)這樣的相似但又不同的地方多的時候,就需要開發(fā)更多的接口來滿足前端的需要。增加了后端開發(fā)人員的工作量和重復(fù)度。


GraphQL簡介
GraphQL是一種新的API標(biāo)準(zhǔn),它提供了一種比REST更有效、更強大和更靈活的替代方案。
它是由Facebook開發(fā)并開源的,現(xiàn)在由來自世界各地的公司和個人組成的大型社區(qū)維護。
GraphQL本質(zhì)上是一種基于api的查詢語言,現(xiàn)在大多數(shù)應(yīng)用程序都需要從服務(wù)器中獲取數(shù)據(jù),這些數(shù)據(jù)存儲可能存儲在數(shù)據(jù)庫中,API的職責(zé)是提供與應(yīng)用程序需求相匹配的存儲數(shù)據(jù)的接口。
它是數(shù)據(jù)庫無關(guān)的,而且可以在使用API的任何環(huán)境中有效使用,我們可以理解為GraphQL是基于API之上的一層封裝,目的是為了更好,更靈活的適用于業(yè)務(wù)的需求變化。


GraphQL 對比 REST API 有什么好處?


與REST多個endpoint不同,每一個的 GraphQL 服務(wù)其實對外只提供了一個用于調(diào)用內(nèi)部接口的端點,所有的請求都訪問這個暴露出來的唯一端點。


GraphQL 實際上將多個 HTTP 請求聚合成了一個請求,將多個 restful 請求的資源變成了一個從根資源 POST 訪問其他資源的 Comment 和 Author 的圖,多個請求變成了一個請求的不同字段,從原有的分散式請求變成了集中式的請求,因此GraphQL又可以被看成是圖數(shù)據(jù)庫的形式。

GraphQL 思考模式

首先要設(shè)計數(shù)據(jù)模型,用來描述數(shù)據(jù)對象,它的作用可以看做是VO,用于告知GraphQL如何來描述定義的數(shù)據(jù),為下一步查詢返回做準(zhǔn)備;
前端使用模式查詢語言(Schema)來描述需要請求的數(shù)據(jù)對象類型和具體需要的字段(稱之為聲明式數(shù)據(jù)獲取);
后端GraphQL通過前端傳過來的請求,根據(jù)需要,自動組裝數(shù)據(jù)字段,返回給前端。

GraphQL執(zhí)行邏輯
使用了GraphQL就要完全拋棄REST了嗎?
GraphQL需要直接對接數(shù)據(jù)庫嗎?
用GraphQL需要對現(xiàn)有的后端服務(wù)進行大刀闊斧的修改嗎?

GraphQL應(yīng)用的基本架構(gòu)

GraphQL特點總結(jié)
聲明式數(shù)據(jù)獲取(可以對API進行查詢): 聲明式的數(shù)據(jù)查詢帶來了接口的精確返回,服務(wù)器會按數(shù)據(jù)查詢的格式返回同樣結(jié)構(gòu)的 JSON 數(shù)據(jù)、真正照顧了客戶端的靈活性。
一個微服務(wù)僅暴露一個 GraphQL 層:一個微服務(wù)只需暴露一個GraphQL endpoint,客戶端請求相應(yīng)數(shù)據(jù)只通過該端點按需獲取,不需要再額外定義其他接口。
傳輸層無關(guān)、數(shù)據(jù)庫技術(shù)無關(guān):帶來了更靈活的技術(shù)棧選擇,比如我們可以選擇對移動設(shè)備友好的協(xié)議,將網(wǎng)絡(luò)傳輸數(shù)據(jù)量最小化,實現(xiàn)在網(wǎng)絡(luò)協(xié)議層面優(yōu)化應(yīng)用。
GraphQL支持的數(shù)據(jù)操作
查詢(Query):獲取數(shù)據(jù)的基本查詢。
變更(Mutation):支持對數(shù)據(jù)的增刪改等操作。
訂閱(Subscription):用于監(jiān)聽數(shù)據(jù)變動、并靠websocket等協(xié)議推送變動的消息給對方。

GraphQL的核心概念:圖表模式(Schema)
對于數(shù)據(jù)模型的抽象是通過類型(Type)來描述的,每一個類型有若干字段(Field)組成,每個字段又分別指向某個類型(Type)。這很像Java、C#中的類(Class)。
GraphQL的Type簡單可以分為兩種,一種叫做Scalar Type(標(biāo)量類型),另一種叫做Object Type(對象類型)。
標(biāo)量類型(Scalar Type)
String
Int
Float
Boolean
Enum
ID

對象類型(Object Type)

類型修飾符(Type Modifier)
列表:[Type]
非空:Type!
列表非空:[Type]!
非空列表,列表內(nèi)容類型非空:[Type!]!



其他類型
接口類型(Interfaces):其他對象類型實現(xiàn)接口必須包含接口所有的字段,并具有相同的類型修飾符,才算實現(xiàn)接口。


聯(lián)合類型(Union Types):聯(lián)合類型和接口十分相似,但是它并不指定類型之間的任何共同字段。幾個對象類型共用一個聯(lián)合類型。

輸入類型(Input Types):更新數(shù)據(jù)時有用,與常規(guī)對象只有關(guān)鍵字修飾不一樣,常規(guī)對象時 type 修飾,輸入類型是 input 修飾。


Graphql 技術(shù)接入架構(gòu)
將Graphql服務(wù)直連數(shù)據(jù)庫的方式:最簡潔的配置,直接操作數(shù)據(jù)庫能減少中間環(huán)節(jié)的性能消耗。

集成現(xiàn)有服務(wù)的GraphQL層:這種配置適合于舊服務(wù)的改造,尤其是在涉及第三方服務(wù)時、依然可以通過原有接口進行交互。

直連數(shù)據(jù)庫和集成服務(wù)的混合模式:前兩種方式的混合。

服務(wù)端實現(xiàn)
C# / .NET
Clojure
Elixir
Erlang
Go
Groovy
Java
JavaScript
Julia
Kotlin
Perl
PHP
Python
R
Ruby
Rust
Scala
Swift
客戶端實現(xiàn)
C# / .NET
Clojurescript
Elm
Flutter
Go
Java / Android
JavaScript
Julia
Swift / Objective-C iOS
Python
R
Graphql的一些服務(wù)
Apollo Engine:一個用于監(jiān)視 GraphQL 后端的性能和使用的服務(wù)。
Graphcool (github): 一個 BaaS(后端即服務(wù)),它為你的應(yīng)用程序提供了一個 GraphQL 后端,且具有用于管理數(shù)據(jù)庫和存儲數(shù)據(jù)的強大的 web ui。Tipe (github): 一個 SaaS(軟件即服務(wù))內(nèi)容管理系統(tǒng),允許你使用強大的編輯工具創(chuàng)建你 的內(nèi)容,并通過 GraphQL 或 REST API 從任何地方訪問它。
AWS AppSync:完全托管的 GraphQL 服務(wù),包含實時訂閱、離線編程和同步、企業(yè)級安全特性以及細(xì)粒度的授權(quán)控制。
Hasura:一個 BaaS(后端即服務(wù)),允許你在 Postgres 上創(chuàng)建數(shù)據(jù)表、定義權(quán)限并使用 GraphQL 接口查詢和操作。
graphiql (npm): 一個交互式的運行于瀏覽器中的 GraphQL IDE。
Graphql Language Service: 一個用于構(gòu)建 IDE 的 GraphQL 語言服務(wù)(診斷、自動完成等) 的接口。
quicktype (github): 在 TypeScript、Swift、golang、C#、C++ 等語言中為 GraphQL 查 詢生成類型。
https://github.com/chentsulin/awesome-graphql。

覺得本文對你有幫助?請分享給更多人
關(guān)注「全棧開發(fā)者社區(qū)」加星標(biāo),提升全棧技能
本公眾號會不定期給大家發(fā)福利,包括送書、學(xué)習(xí)資源等,敬請期待吧!
如果感覺推送內(nèi)容不錯,不妨右下角點個在看轉(zhuǎn)發(fā)朋友圈或收藏,感謝支持。
好文章,留言、點贊、在看和分享一條龍吧??
