02.16 還在用restful接口?你out了!如今接口開發都這麼做

GraphQL,代替restful接口的新一代API查詢語言!

還在用restful接口?你out了!如今接口開發都這麼做

GraphQL


1. 基本介紹


1.1 簡介

GraphQL是一種新的API標準,它提供了一種比REST更有效、更強大和更靈活的替代方案。它是由Facebook開發並開源的,現在由來自世界各地的公司和個人組成的大型社區維護。

API已經成為軟件基礎結構中無處不在的組件。簡而言之,API定義了客戶客戶端如何從服務器加載數據。

在其核心部分,GraphQL支持聲明式數據獲取,客戶端可以在其中準確地指定需要從API獲取哪些數據。與返回固定數據結構的多個端點(multiple endpoints)不同,GraphQL服務器只公開單個端點(a single endpoint),並使用客戶機請求的準確數據進行響應。

1.2 GraphQL:一種API查詢語言

現在的大多數應用程序都需要從服務器獲取存儲在數據庫中的數據。API的職責是為存儲的數據提供符合應用程序需求的接口。

GraphQL經常與數據庫技術混淆。這是一種誤解,GraphQL是API(而不是數據庫)的查詢語言。從這個意義上說,它與數據庫無關,可以在使用API的任何上下文中有效地使用。

1.3 一個可以代替REST的高效選擇

想要了解更多為什麼使用GraphQL的主要原因請複製以下鏈接到瀏覽器打開:https://www.prisma.io/blog/top-5-reasons-to-use-graphql-b60cfa683511

REST是公開服務器數據的一種流行方法。當REST的概念被開發時,客戶端應用程序相對簡單,開發速度遠不及今天。因此REST非常適合於許多應用程序。然而,API環境在過去幾年中發生了根本的變化。特別是,有三個因素一直在挑戰API的設計方式:

  1. 手機等移動終端使用的增加產生了對高效數據加載的需求Facebook開發GraphQL的最初原因是移動應用的增加、低功率設備和鬆散的網絡。GraphQL最小化了需要通過網絡傳輸的數據量,從而極大地改進了在這些條件下運行的應用程序。
  2. 各種不同的前端框架和平臺運行客戶端應用程序的前端框架和平臺的異構環境使得構建和維護一個滿足所有需求的API變得非常困難。使用GraphQL,每個客戶端都可以準確地訪問所需的數據。
  3. 快速開發&對快速特性開發的期望持續部署已經成為許多公司的標準,快速的迭代和頻繁的產品更新是必不可少的。使用REST API,服務器公開數據的方式通常需要修改,以滿足客戶端的特定需求和設計更改。這阻礙了快速開發實踐和產品迭代。

1.4 歷史,背景和採用

1.4.1 GraphQL 不僅僅 適用於React開發人員

2012年,Facebook開始在其原生移動應用程序中使用GraphQL。不過,有趣的是,GraphQL主要是在web技術上下文中使用的,在本地移動領域只獲得很少的關注。

Facebook第一次公開談論GraphQL是在React.js 會議 2015上,會議不久後Facebook宣佈他們開放GraphQL源代碼的計劃。因為Facebook總是在使用React的情況下談論GraphQL,而非React開發人員需要花一段時間才會明白:GraphQL絕不是一種僅限於與React一起使用的技術。

1.4.2 快速成長的社區

事實上,GraphQL是一種技術,可以在客戶端與API通信的任何地方使用。有趣的是,Netflix和Coursera等其他公司也在研究類似的想法,以提高API交互的效率。Coursera設想了一種類似的技術,讓客戶端明確自己的數據需求,Netflix甚至開放了名為Falcor的解決方案的源代碼。在GraphQL開源之後,Coursera完全取消了自己的努力,加入了GraphQL的行列。

今天,GraphQL被許多不同的公司用於生產中,如GitHub、Twitter、Yelp和Shopify——僅舉幾個例子。

還在用restful接口?你out了!如今接口開發都這麼做

使用GraphQL的公司


儘管GraphQL是如此年輕的技術,但它已經被廣泛採用。瞭解還有哪些公司在生產中使用GraphQL。


問題:下面哪個描述是正確的?

  • [ ] GraphQL是一種數據庫技術
  • [ ] GraphQL只能與SQL一起使用
  • [✔] GraphQL是由Facebook發明的
  • [ ] GraphQL是由Netflix和Coursera開發的

2. GraphQL是更好的REST


在過去的十年中 REST 已經成為設計web api的標準(儘管還很模糊)。它提供了一些很棒的想法,比如無狀態服務器和對資源的結構化訪問。然而,REST API已經被證明過於僵化,無法跟上訪問它們的客戶端快速變化的需求。

GraphQL的開發是為了滿足對更大靈活性和效率的需求!它解決了開發人員在與REST API交互時遇到的許多缺點和低效。

為了說明REST和GraphQL在從API獲取數據時的主要區別,讓我們考慮一個簡單的示例場景:在博客應用程序中,應用程序需要顯示特定用戶的文章標題。同一屏幕還顯示該用戶最後3個關注者的名稱。如何使用REST和GraphQL解決這種情況?

想要了解更多關於開發人員為什麼喜歡GraphQL的信息以下鏈接到瀏覽器打開:

https://www.prisma.io/blog/top-5-reasons-to-use-graphql-b60cfa683511

2.1 獲取數據的方式:REST vs GraphQL

使用REST API,您通常會通過訪問多個端點來收集數據。在本例中,這些端點可以是 /users/ 端點來獲取初始用戶數據。其次,可能存在一個 /users//posts 端點,該端點返回用戶的所有文章。第三個端點是 /users//follower ,它返回每個用戶的follower列表。

還在用restful接口?你out了!如今接口開發都這麼做

REST Request Step


使用REST,你必須向不同的端點發出三個請求來獲取所需的數據。此外你還可能獲取到端點返回的你並不需要的額外信息。

而在GraphQL中,只需向GraphQL服務器發送一個包含具體數據需求的查詢。然後,服務器會返回一個滿足這些需求的JSON對象。

還在用restful接口?你out了!如今接口開發都這麼做

GraphQL Request


使用GraphQL,客戶端可以在查詢中準確地指定所需的數據。請注意,服務器響應的結構完全遵循查詢中定義的嵌套結構。

2.2 不再是多取(Overfetching)和少取(Underfetching)數據

REST最常見的問題之一是獲取過多和不足。這是因為客戶端下載數據的唯一方法是訪問返回固定數據結構的端點。很難將API設計成能夠為客戶提供準確數據需求的方式。

“Think in graphs, not endpoints.”——這是GraphQL的共同發明人Lee Byron從4年的GraphQL中總結的經驗教訓。

http://www.graphql.com/articles/4-years-of-graphql-lee-byron

2.2.1 Overfetching:取到多餘的數據

Overfetching意味著客戶端取到的信息比應用程序實際需要的要多。例如,假設一個界面只需要顯示包含用戶姓名的用戶列表,在REST API中,客戶端通常會請求 /users 端點並接收一個包含用戶數據的JSON數組。然而,服務器響應可能會返回包含更多關於用戶的信息,例如他們的生日或地址——這些信息對於客戶端是無用的,因為它只需要顯示用戶的姓名。

2.2.2 Underfetching:獲取數據不足和 n+1 問題

另一個問題是獲取數據不足和 n + 1 個請求的問題。取不到通常意味著特定端點不能提供足夠的所需信息。客戶端必須發出額外的請求來獲取它需要的所有東西。這可能會升級到這樣一種情況:客戶端首先需要下載元素列表,然後需要為每個元素髮出一個額外的請求來獲取所需的數據。

例如,考慮該應用程序還需要為每個用戶顯示最後三個關注者。這個API提供了額外的端點 /users/<user-id>/follower/<user-id>。為了能夠顯示所需的信息,應用程序必須向 /users 端點發出一個請求,然後為每個用戶命中 /users/<user-id>/follower/<user-id> 端點。

2.3 前端的快速產品迭代

REST API的一個常見模式是根據應用程序內部的視圖來構造端點。這很方便,因為它允許客戶端通過訪問相應的端點來獲得特定視圖所需的所有信息。

這種方法的主要缺點是不允許在前端進行快速迭代。對UI所做的每一次更改都有一個很高的風險,即現在所需的數據比以前更多(或更少)。因此,後端也需要根據新的數據需求進行調整。這降低了生產效率,並明顯降低了將用戶反饋整合到產品中的能力。

而GraphQL解決了這個問題。由於GraphQL的靈活性,客戶端上的更改無需在服務器上做任何額外的工作。由於客戶端可以指定準確的數據需求,所以當前端的設計和數據需求發生變化時,不需要後端工程師進行調整。

2.4 後端的深刻分析

GraphQL允許你對後端請求的數據有細粒度的瞭解。由於每個客戶端準確地指定了它感興趣的信息,因此有可能深入瞭解可用數據是如何被使用的。這就有了更多好處,例如這可以幫助API的演變和廢棄不再由任何客戶端請求使用的特定字段等。

使用GraphQL,你還可以對服務器處理的請求進行低級性能監視。GraphQL使用解析器函數的概念來收集客戶端請求的數據。對這些解析器的性能進行檢測和測量,可以對系統中的瓶頸提供至關重要的見解。

2.5 模式(Schema )和類型(Type)系統的好處

GraphQL使用強類型系統來定義API的功能。API中公開的所有類型都是使用GraphQL模式定義語言(SDL)在模式中編寫的。此模式充當客戶端和服務器之間的契約,用於定義客戶端如何訪問數據。

一旦定義了模式,從事前端和後端工作的團隊就可以在沒有進一步通信的情況下完成工作,因為他們都知道通過網絡發送的數據的確切結構。

前端團隊可以通過模擬(Mock)所需的數據結構輕鬆地測試他們的應用程序。一旦服務器準備就緒,就可以通過切換開關,讓客戶端應用程序從實際API加載數據。


問題:GraphQL模式和強類型系統的好處是什麼?

  • [ ] 它們與Javascript類型系統配合得很好
  • [✔] 一旦定義了模式,前端和後端團隊就可以彼此獨立地工作
  • [ ] 它解決了 n+1 請求問題
  • [ ] 偏題:GraphQL沒有類型系統

3. 核心概念


在本章中,您將瞭解GraphQL的一些基本語言結構。這包括對定義類型以及發送查詢(queries)和更新(mutations)的語法的初步瞭解。我們還為你準備了一個基於graphql-up(https://www.npmjs.com/package/graphql-up)的沙箱環境,你可以使用它來試驗您所學的知識。

3.1 模式定義語言(SDL)

GraphQL有自己的類型系統,用於定義API的模式。編寫模式的語法稱為模式定義語言(Schema Definition Language, SDL)。

下面是我們如何使用SDL定義一個簡單類型Person的例子:

type Person {

name: String!

age: Int!

}

這個類型有兩個字段,它們分別是 name age ,類型是 String Int 。類型後面的 ! 此字段是必須的。

還可以表示類型之間的關聯關係。在博客應用程序的例子中,一篇文章 Post 可以對應一個作者Person,可以形成多對一的關聯關係:

type Post {

title: String!

author: Person!

}

反之,一個人可能會發表多篇文章,這種一對多的關聯關係在

Person類型上的表示如下:

type Person {

name: String!

age: Int!

posts: [Post!]!

}

注意,我們只是在 Person Post 之間創建了一對多的關係,因為 Person 上的 posts 字段實際上是一個 Post 數組。

3.2 使用查詢獲取數據

在使用REST API時,數據是從特定端點加載的。每個端點返回的信息都有一個明確定義的結構。這意味著客戶端的數據需求有效地編碼在它所連接的URL中。

GraphQL中採用的方法完全不同。GraphQL API通常只公開一個端點,而不是返回固定數據結構的多個端點。這是因為返回的數據結構不是固定的。相反,它是完全靈活的,可以讓客戶端決定實際需要什麼數據。

這意味著客戶端需要向服務器發送更多的信息來表達其數據需求——這些信息稱為查詢。

3.2.1 基本查詢

讓我們看一個客戶端可以發送到服務器的查詢示例:

{

allPersons {

name

}

}

此查詢中的 allPersons 字段稱為查詢的根字段。根字段後面的所有內容都稱為查詢的有效負載(payload)。在該查詢的有效負載中指定的唯一字段是 name

Person:

id | name | age

cjs1lw3sh16vd0154o0q0kcav | Johnny | 23

cjs1lw3uy16vj0154ykmo54bs | Sarah | 20

cjs1lw3w216vn0154ef6q00i9 | Alice | 20

這個查詢將返回當前存儲在數據庫中的所有人員的列表。下面是上述示例的返回數據:

{

"allPersons": [

{ "name": "Johnny" },

{ "name": "Sarah" },

{ "name": "Alice" }

]

}

注意,在響應結果中每個 Person 只有 name 字段,但是服務器並沒有返回 age 字段。這正是因為 name 是查詢中指定的唯一字段。

如果客戶端還需要用戶的年齡,只需稍微調整查詢,在查詢聲明中包含新字段:

{

allPersons {

name

age

}

}

則服務器將會返回結果:

{

"data": {

"allPersons": [

{

"name": "Johnny",

"age": 23

},

{

"name": "Sarah",

"age": 20

},

{

"name": "Alice",

"age": 20

}

]

}

}

GraphQL的主要優勢之一是允許自然地查詢嵌套信息。例如,如果你想加載一個人寫的所有文章,你可以簡單地按照你的類型結構來請求這些信息:

{

allPersons {

name

age

posts {

title

}

}

}

然後服務器將會返回如下數據:

{

"data": {

"allPersons": [

{

"name": "Johnny",

"age": 23,

"posts": [

{

"title": "GraphQL is awesome"

},

{

"title": "Relay is a powerful GraphQL Client"

}

]

},

{

"name": "Sarah",

"age": 20,

"posts": [

{

"title": "How to get started with React & GraphQL"

}

]

},

{

"name": "Alice",

"age": 20,

"posts": []

}

]

}

}

3.2.2 查詢參數

在GraphQL中,如果在模式(schema)中指定了參數(arguments),則每個字段可以有零個或多個參數。例如,allPersons字段的最後一個參數只能返回特定數量的人員。下面是相應的查詢:

{

allPersons(last: 2) {

name

}

}

返回結果:

{

"data": {

"allPersons": [

{

"name": "Sarah"

},

{

"name": "Alice"

}

]

}

}

好了,GraphQL基本的介紹就到這裡,如果你對GraphQL感興趣,可以關注並私信回覆我“GraphQL PPT”,獲取我製作的GraphQL介紹的PPT。

使用頭條搜索更簡單~!

如果你想了解更多關於“GraphQL”的相關內容,你可以直接使用今日頭條app上方的搜索框輸入“GraphQL”,就可以搜到很多相關的介紹啦。快去搜搜看吧!

還在用restful接口?你out了!如今接口開發都這麼做



我是一隻好奇的貓,致力於分享技術乾貨和心得。關注我,關注不一樣的世界。


分享到:


相關文章: