- 原文地址:A Beginner’s Guide to GraphQL
- 原文做者:Leonardo Maldonado
- 項目倉庫:GraphQL-Guide-For-Beginner
- 譯者:Seymoe
- 譯者注:此文爲本人第一篇譯文,本人做爲無 GraphQL 使用背景的初學者,翻譯過程亦是學習過程。若是發現譯文有錯誤或者表述不當的地方敬請指正,十分感謝!
API 是互聯網行業討論最多的術語之一,可是不少人並不確切知道 API 究竟是什麼。基本上,API 表明應用程序編程接口(Application Programming Interface)。顧名思義,它至關於一個「界面」,令人們(開發人員、用戶、消費者)可以經過它與數據進行交互。php
你能夠理解爲 API 就像是個酒保,你向酒保要一杯酒,他便把一杯你想要的酒遞給你,看起來很簡單的事,還有什麼問題呢?git
構建 API 不是一件困難的事,但學習和理解具體的 API 可能存在必定的困難。多數開發者都會使用你的 API 去開發功能或者只是消費數據,這就要求 API 須要儘量保持乾淨、直觀。精心設計、直觀性強的 API 會很是容易理解和使用。github
一直以來,咱們都在用 REST 來構建 API,使用這種方式會存在一些問題,例如:數據庫
爲了解決以上的相似問題,Facebook 創造了 GraphQL。我認爲 GraphQL 是當代構建 API 的最佳方式,本文將闡述爲何你應該開始學習 GraphQL,讓你瞭解 GraphQL 的工做原理,以及如何使用 GraphQL 建立設計精良、高效而且功能強大的 API。npm
你可能已經據說過 GraphQL,由於不少開發者和公司都在使用它。因爲 GraphQL 是開源的,因此社區也是很龐大的存在。讓咱們在實踐中學習 GraphQL 的工做原理,領略它的魔力了。編程
GraphQL (譯者注:中文文檔)是 Facebook 開發的一種開源查詢語言。它爲咱們提供了一種更有效的方式來設計、建立和消費咱們的 API 。基本上,它是 REST 的替代品。json
GraphQL 有不少功能,例如:數組
這是對 GraphQL 的基本介紹,解釋了爲何它如此強大以及爲何它現在得到了不少人氣。若是想了解更多相關信息,我建議訪問 GraphQL 網站去了解。瀏覽器
本文主要目的不是學習如何配置 GraphQL 服務器,因此咱們如今不會深刻研究。本文的目標是瞭解 GraphQL 在實踐中的工做原理,所以咱們將使用一個叫作☄️Traderpack的零配置GraphQL服務器庫。bash
第一步,咱們須要建立一個新文件夾,你能夠隨意命名。我將它命名爲 graphql-server :
mkdir graphql-server
複製代碼
假定你已經在本身的機器中安裝了 npm 或 yarn。若是你不知道它們是什麼,npm 和 yarn 是 JavaScript 編程語言的包管理器。對於 Node.js,默認包管理器是 npm。
在建立的文件夾中,輸入如下命令:
npm init -y
複製代碼
若是你使用 yarn :
yarn init
複製代碼
npm 會建立一個 package.json
文件,項目安裝的全部依賴項和命令都在這個文件中。
接下來,咱們來安裝本項目要使用的惟一依賴項,☄️Traderpack 容許你建立零配置的 GraphQL 服務器。因爲咱們剛剛開始使用 GraphQL,這將幫助咱們繼續學習更多內容,而沒必要擔憂服務器配置。
打開終端進入項目文件夾,鍵入如下命令:
npm install --save-dev graphpack
複製代碼
若是你使用 yarn,應該這樣:
yarn add --dev graphpack
複製代碼
安裝 Graphpack 以後,轉到 package.json
文件中的腳本,並在其中輸入如下代碼:
"scripts": {
"dev": "graphpack",
"build": "graphpack build"
}
複製代碼
咱們將建立一個名爲 src 的文件夾做爲整個服務器中惟一的文件夾,而後在 src 文件夾中建立三個文件。
譯者注:使用 VSCode 的童鞋能夠安裝 `GraphQL for VSCode` 插件進行語法高亮
首先,咱們建立第一個文件,名叫 schema.graphql
,並在這個文件中輸入如下代碼:
type Query {
hello: String
}
複製代碼
這個 schema.graphql
文件將是咱們的整個 GraphQL 架構,稍後我會解釋它的做用。
接下來,在 src 文件夾中建立第二個文件 resolvers.js
,並在這個文件中輸入如下代碼:
import { users } from "./db"
const resolvers = {
Query: {
hello: () => "Hello World!"
}
}
export default resolvers
複製代碼
這個 resolvers.js
文件將是咱們提供將 GraphQL 操做轉換爲數據的指令的方式。
最後,在src文件夾中建立第三個文件 db.js
,並在這個文件中輸入如下代碼:
export let users = [
{ id: 1, name: "John Doe", email: "john@gmail.com", age: 22 },
{ id: 2, name: "Jane Doe", email: "jane@gmail.com", age: 23 }
]
複製代碼
在本教程中,咱們沒有使用真實數據庫。因此這個 db.js
文件將模擬數據庫,僅用於學習目的。
如今咱們的src文件夾應以下所示:
src
|--db.js
|--resolvers.js
|--schema.graphql
複製代碼
如今,若是你運行命令 npm run dev
,或者若是你正在使用yarn,則運行 yarn dev
,應該在終端中看到此輸出:
如今能夠用瀏覽器打開 localhost:4000
,這意味着咱們已準備好開始在 GraphQL 中編寫咱們的第一個 queries(查詢),mutations(突變)和 subscriptions(訂閱)。
若是感興趣能夠看看 GraphQL Playground,這是一個功能強大的 GraphQL IDE,可用於更好的開發工做流程。若是你想了解有關 GraphQL Playground 的更多信息,請單擊此處。
GraphQL 有本身的語言類型,用於編寫 Schema(模式)。這是一種人類可讀的模式語法,稱爲 Schema Definition Language - 模式定義語言(SDL)。不管使用何種技術,SDL都是相同的 - 你能夠將其用於你想要的任何語言或框架。這種模式語言很是有用,由於它會讓你很容易直觀的理解你的 API 將具備哪些類型。
Types(類型)是 GraphQL 最重要的特性之一。Types 是自定義對象,表示 API 的外觀。舉個例子,若是你正在構建社交媒體應用程序,那麼你的 API 可能會有 Posts
、Users
、Likes
、Groups
等 Types。
Types 下有 fields(字段),這些字段返回特定類型的數據。例如,咱們要建立一個 User 類型,咱們應該有 name
、email
和 age
等字段。字段能夠是任何類型,並始終返回一種數據類型,好比 Int、Float、String、Boolean、ID、對象類型列表或自定義對象類型。
如今編寫咱們的第一個 Type,轉到 schema.graphql
文件並用如下內容替換已存在的 Query
類型:
type User {
id: ID!
name: String!
email: String!
age: Int
}
複製代碼
每一個 User
都將擁有一個 ID
,所以咱們爲其提供了 ID
類型。User
也會有一個 name
和 email
,因此咱們給它們 String
類型,年齡咱們給了 Int
類型。很簡單吧?
數據類型後面的 !
表示該字段非空(non-nullable),這意味着這些帶 !
的字段必須在每一個查詢中返回一些數據。
在 GraphQL 中有三個主要概念:
這三個主要概念我會一一解釋。
簡單來講,GraphQL 中的查詢就是獲取數據的方式。GraphQL 中的查詢會得到所需的確切數據。很少也很多。這對咱們的 API 產生了巨大的積極影響 - 再也不像咱們使用 REST API 那樣過分獲取或提取不足信息。
讓咱們來中建立一個查詢類型,首先,在 schema.graphql
中添加一個名爲 Query
的新類型:
type Query {
users: [User!]!
}
複製代碼
users
查詢將返回給咱們一個或多個用戶的數組。它不會返回 null
,由於咱們在後面加了 !
,這意味着它是一個不可爲空的查詢,應該老是返回一些東西。
既然能返回多個,咱們也能返回一個特定用戶,在 Query
類型中添加一個新的查詢 user
:
type Query {
users: [User!]!
+ user(id: ID!): User!
}
複製代碼
你會發現查詢可以傳遞參數,查詢特定用戶的時候把用戶的 id
做爲參數傳入。
那麼 GraphQL 如何知道去哪獲取到數據返回呢?這就是 resolvers.js
的做用,它會告訴 GraphQL 如何以及在何處獲取數據。
打開 resolvers.js
文件,更改一下代碼:
import { users } from "./db"
const resolvers = {
Query: {
user: (parent, { id }, context, info) => {
return users.find(user => user.id === id)
},
users: (parent, args, context, info) => {
return users
}
}
}
export default resolvers
複製代碼
解釋一下以上代碼是如何工做的:
user
函數中,咱們將 id
做爲參數傳遞,而後返回與傳遞的 id
匹配的特定用戶users
函數中,咱們只是返回已存在的 users
數組,它會返回全部的用戶如今,咱們將測試咱們的查詢是否正常工做。瀏覽器打開 localhost:4000
,在左邊輸入如下代碼而後點運行按鈕:
query {
users {
id
name
email
age
}
}
複製代碼
試試返回 id 爲 1 的用戶:
query {
user(id: 1) {
id
name
email
age
}
}
複製代碼
在 GraphQL 中,Mutations 是修改服務器上的數據並獲取更新數據的方式。你能夠理解爲相似 REST 的CUD(CREATE,UPDATE,DELETE)。
咱們來建立一個類型突變,咱們全部的突變都將在這種類型中結束。在 schema.graphql
文件中編寫一個名爲 mutation
的新類型:
type Mutation {
createUser(id: ID!, name: String!, email: String!, age: Int): User!
updateUser(id: ID!, name: String, email: String, age: Int): User!
deleteUser(id: ID!): User!
}
複製代碼
上述代碼建立了三個 Mutation:
createUser
- 咱們傳入的參數 id
、name
、email
、age
,應該返回一個新的用戶updateUser
- 傳入 id
和新的 name
、email
與 age
, 應該返回一個更新後的用戶deleteUser
- 傳入 id
,應該返回被刪除掉用戶的信息如今,咱們去 resolvers.js
文件中,在 Query
對象下方插入一個新的 Mutation
對象。
Mutation: {
createUser: (parent, { id, name, email, age }, context, info) => {
const newUser = { id, name, email, age }
users.push(newUser)
return newUser
},
updateUser: (parent, { id, name, email, age }, context, info) => {
let newUser = users.find(user => user.id === id)
newUser.name = name
newUser.email = email
newUser.age = age
return newUser
},
deleteUser: (parent, { id }, context, info) => {
const userIndex = users.findIndex(user => user.id === id)
if (userIndex === -1) throw new Error("User not found.")
const deletedUsers = users.splice(userIndex, 1)
return deletedUsers[0]
}
}
複製代碼
該去 localhost:4000
看看咱們寫的 Mutations 是否有效了,在頁面上輸入:
mutation {
createUser(id: 3, name: "Robert", email: "robert@gmail.com", age: 21) {
id
name
email
age
}
}
複製代碼
你也能夠嘗試一下其餘的 Mutation。
正如我以前所說,Subscriptions (訂閱)是你與服務器保持實時鏈接的方式。這意味着不管什麼時候在服務器中發生事件,而且每當調用該事件時,服務器都會將相應的數據發送到客戶端。經過使用訂閱,你能夠將應用程序更新爲不一樣用戶之間的最新更改。
最基本的訂閱示例:
subscription {
users {
id
name
email
age
}
}
複製代碼
你會說它與查詢很是類似,但它的工做方式和查詢不一樣。當服務器中的某些內容更新時,服務器將運行訂閱中指定的 GraphQL 查詢,並將更新的結果發送到客戶端。我並不打算在這篇文章中使用訂閱,但若是你想了解更多關於它們的信息,請點擊此處。
如你所見,GraphQL 是一項很是強大的新技術。它爲咱們提供了構建更好和精心設計的 API 的真正能力。這就是爲何我建議你如今開始學習它。
對我來講,它最終將取代 REST。
感謝閱讀文章,請在下面發表評論!