阿里雲最近在作活動,低至2折,有興趣能夠看看:
https://promotion.aliyun.com/...
爲了保證的可讀性,本文采用意譯而非直譯。php
想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等着你!html
今天最常討論的術語之一是 API,不少人不知道 API 究竟是什麼,API 是 Application Programming Interface(應用程序編程接口)。顧名思義,它是一些預先定義的函數,目的是提供應用程序與開發人員基於某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼,或理解內部工做機制的細節。前端
你能夠將 API 想象成一個酒保。你向酒保要一杯酒,他們會給你想要的。簡單,可是傳統的 REST API 有什麼問題的呢?git
自從現代 Web 出現以來,構建 Api 並不像聽起來那麼困難,可是學習和理解 Api 纔是比較難。開發人員是大多數據使用你的 API 來構建某些內容或僅使用數據。因此你的 API 應該儘量的簡潔和直觀, 好的 API 是很是容易使用和學習的。直觀,在開始設計 API 時常要記住的一點。github
咱們已經使用 REST 構建 Api 很長時間了。隨之而來的也有一些問題,在使用 REST 設計構建 API 時,你會遇到如下問題:數據庫
* 信息的獲取有多有少npm
爲了解決這些問題,Facebook 建立了 GraphQL。如今,做者認爲 GraphQL 是構建 Api 的最佳方式。這篇文章將告訴你爲何要學習瞭解一下 GraphQL。編程
GraphQL 是 Facebook 開發的一種開源查詢語言。它爲咱們提供了一種更有效的設計、建立和使用 Api的方法。從根本上說,它是 REST 的替代品。json
GraphQL有不少特性,好比:segmentfault
這是對 GraphQL 的基本介紹——爲何它這麼強大,爲何它如今這麼流行。若是你想了解更多關於它的信息,能夠訪問 GraphQL網站 學習。
本文的主要目的不是學習如何設置 GraphQL服務器,因此咱們如今尚未深刻研究。 文本的目標是瞭解 GraphQL 在實踐中的工做原理,所以這裏使用簡約的零配置 GraphQL 服務器的 Graphpack。
開始項目前,首先咱們建立一個新文件名爲 graphql-server, 在 mac 終端執行
mkdir graphql-server
接着進入該文件,執行
npm init -y
或者執行
yarn init
npm 將建立一個包 package.json
文件,這個包是你安裝的全部依賴項和命令。
如今,咱們要安裝惟一的依賴項。
Graphpack 容許建立零配置的 GraphQL 服務器。因爲剛剛開始使用 GraphQL,這將幫助咱們繼續學習GraphQL 更多的內容,而沒必要擔憂服務器配置,執行如下命令:
npm install --save-dev graphpack
或者使用 yarn 安裝:
yarn add --dev graphpack
安裝 Graphpack 以後,轉到 package.json文件中的腳本,並在其中輸入如下代碼:
"scripts": { "dev": "graphpack", "build": "graphpack build" }
接着建立一個名爲 src 的文件夾,它將是整個服務器中惟一的文件夾。
在 src 文件夾中建立一個名爲 schema.graphql 的文件,並寫入如下代碼:
type Query { hello: String }
在 schema.graphql 文件將是咱們的整個 GraphQL的模式(Schema)。
接着在 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 dev
啓動服務
在瀏覽器打開 localhost:4000
。這裏就實現咱們在 GraphQL 中的第一個查詢,更改和訂閱,打開界面以下:
你能夠看到 GraphQL Playground,這是一個功能強大的 GraphQL IDE,可用於更好的開發工做流程。 若是你想了解有關 GraphQL Playground的更多信息,請單擊此處。
GraphQL 有本身的語言類型,用於編寫模式。 這是一種人類可讀的模式語法,稱爲規範與描述語言(SDL)。不管使用何種技術,SDL 都是相同的 - 你能夠將其用於你想要的任何語言或框架。
這種模式語言很是有用,由於它更直觀的看出 API 具備哪些類型,一看到 API 就知道怎麼使用。
類型是 GraphQL 最重要的特性之一。類型是表示 API 外觀的自定義對象。例如,若是你正在構建一個社交媒體應用程序,那麼你的 API 應該具備諸如文章、用戶、贊、組等類型。
類型具備字段,這些字段返回特定類型的數據。 例如,咱們要建立一個 User
類型,咱們應該有一些 name
,email
和 age
字段。 類型字段能夠是任何類型,並始終返回一種數據類型,如 Int,Float,String,Boolean,ID,對象類型列表或自定義對象類型。
如今編寫的第一個 Type,在 schema.graphql 文件中用如下內容替換已存在的 Query 類型:
type User { id: ID! name: String! email: String! age: Int }
每一個用戶都將擁有一個 ID,所以爲其提供了 ID 類型。 用戶也會有一個 name
和 email
,因此給它一個字符串類型和一個 Int 類型。
可是,在每一行的結尾的 !
呢? 感嘆號表示字段不可爲空,這意味着每一個字段必須在每一個查詢中返回一些數據。 User 中惟一能夠爲空的字段是 age
。
在GraphQL中,有三個主要概念:
爲了簡單地解釋這一點,GraphQL 中的查詢是獲取數據的方式。關於 GraphQL 中的查詢,最吸引人的地方之一就是你將得到所需的確切數據,很少很多。這對咱們的 API 產生了巨大的積極影響——再也不像 REST API 那樣獲取過多或不足的信息。
咱們將在 GraphQL 中建立第一個類型的 Query。 咱們全部的查詢都將以此類型結束。 首先,在文件 schema.graphql 編寫一個名爲Query 的新類型:
type Query { users: [User!]! }
這很簡單:用戶查詢將返回給咱們一個或多個用戶的數組。 它不會返回 null
,由於咱們放入了 !
,這意味着它是一個不可爲空的查詢, 它總會返回一些數據。
但咱們也能夠返回特定用戶。 爲此,建立一個名爲 user
的新查詢。 在咱們的 Query 類型中,寫如下代碼:
user(id: ID!): User!
如今 Query 類型應該是這樣的:
type Query { users: [User!]! user(id: ID!): User! }
如上所見,使用 GraphQL 中的查詢,還能夠傳遞參數。在本例中,要查詢特定用戶,因此要傳遞其用戶的 ID。
可是,你可能想知道: GraphQL 如何知道從哪裏獲取數據? 這就是爲何咱們應該有一個 resolvers.js 文件。該文件告訴 GraphQL 它將如何以及在何處獲取數據。
首先,看看咱們的 resolvers.js 文件並裏該文件裏導入 db.js
文件。咱們剛纔建立的 resolvers.js 文件內容以下:
import { users } from "./db"; const resolvers = { Query: { hello: () => "Hello World!" } }; export default resolvers;
如今,咱們將建立第一個 Query,在 resolvers.js 文件並替換 hello
函數。 如今 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
匹配的特定 user,這很簡單。
在 users
函數中,咱們只是返回已存在的 users 數組,這個數組存放的是全部的用戶。
如今,咱們將測試查詢是否工做正常,轉到 localhost:4000,輸入如下代碼:
query { users { id name email age } }
它應該返回給你咱們全部的用戶。
若是想返回特定的用戶:
query { user(id: 1) { id name email age } }
在 GraphQL 中,更改是修改服務器上的數據並獲取更新數據的方式, 你能夠像 REST 的CUD(建立,更新,刪除)同樣思考。
在 GraphQL 中建立咱們的第一個類型修改,這裏全部的修改都將在這個類型中結束。 首先,在 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! }
這裏主要定義三個修改數據的方法:
如今,在 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]; } }
如今 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; } }, 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]; } } }; export default resolvers;
如今,咱們要測試咱們的 mutations 是否正常。轉到localhost:4000,輸入如下代碼:
mutation { createUser(id: 3, name: "Robert", email: "robert@gmail.com", age: 21) { id name email age } }
如我以前所說,訂閱是你與服務器保持實時鏈接的方式。這意味着不管什麼時候在服務器中發生事件,而且每當調用該事件時,服務器都會將相應的數據發送到客戶端。
經過訂閱,你可讓你的應用在不一樣的用戶之間保持更新。
基本訂閱是這樣的:(sample.graphql )
subscription { users { id name email age } }
你會說它很是相似於查詢,是的, 但它的工做方式不一樣。
當服務器中發生更新時,服務器將運行訂閱中指定的 GraphQL 查詢,並向客戶機發送一個新更新的結果。
在這篇文章中,咱們不打算討論訂閱,可是若是你想閱讀更多關於訂閱的信息,請單擊這裏。
如你所見,GraphQL 是一項很是強大的新技術。 它爲咱們提供了構建更好和精心設計的API的真正能力。 這就是爲何做者建議你如今開始學習它,從本文本做者的角度來講,它最終將取代 REST。
原文:
https://medium.freecodecamp.o...
你的點贊是我持續分享好東西的動力,歡迎點贊!
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
https://github.com/qq44924588...
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。