- GraphQL 教程
- GraphQL - 首頁
- GraphQL - 簡介
- GraphQL - 環境搭建
- GraphQL - 架構
- GraphQL - 應用元件
- GraphQL - 示例
- GraphQL - 型別系統
- GraphQL - 模式 (Schema)
- GraphQL - 解析器 (Resolver)
- GraphQL - 查詢
- GraphQL - 變異 (Mutation)
- GraphQL - 驗證
- GraphQL - JQuery 整合
- GraphQL - React 整合
- GraphQL - Apollo Client
- GraphQL - 客戶端身份驗證
- GraphQL - 快取
- GraphQL 有用資源
- GraphQL - 快速指南
- GraphQL - 有用資源
- GraphQL - 討論
GraphQL - 查詢
GraphQL 操作可以是讀取或寫入操作。GraphQL 查詢用於讀取或獲取值,而變異 (Mutation) 用於寫入或釋出值。無論哪種情況,操作都是一個簡單的字串,GraphQL 伺服器可以解析該字串,並以特定格式的資料進行響應。通常用於移動和 Web 應用程式的流行響應格式是 JSON。
定義查詢的語法如下:
//syntax 1
query query_name{ someField }
//syntax 2
{ someField }
以下是一個查詢示例:
//query with name myQuery
query myQuery{
greeting
}
// query without any name
{
greeting
}
從上面的例子可以看出,query 關鍵字是可選的。
GraphQL 查詢有助於減少資料過度獲取。與 RESTful API 不同,GraphQL 允許使用者限制應從伺服器獲取的欄位。這意味著查詢更小,網路流量更少;從而減少響應時間。
圖示 1 - 使用自定義欄位查詢學生模型
在這個例子中,我們有一組儲存在 json 檔案中的學生。每個學生模型都有 firstName、lastName 和 id 等欄位,但沒有 fullName。在這裡,我們將討論如何進行查詢以檢索所有學生的 fullName。為此,我們需要在模式解析器中建立 fullName 欄位。
讓我們看看如何使用以下步驟完成此圖示:
步驟 1 - 下載並安裝專案所需的依賴項
建立一個名為 **query-app** 的資料夾。從終端將目錄更改為 **query-app**。稍後,按照“環境搭建”章節中說明的步驟 3 到 5 進行操作。
步驟 2 - 建立模式 (Schema)
在專案資料夾 query-app 中新增 **schema.graphql** 檔案,並新增以下程式碼:
type Query {
greeting:String
students:[Student]
studentById(id:ID!):Student
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
}
請注意,**students.json** 檔案中沒有 *fullName* 欄位。但是,我們需要透過查詢來獲取學生的 *fullName*。在這種情況下,*fullName* 將是一個數據源中不存在的自定義欄位。
步驟 3 - 建立解析器 (Resolver)
在專案資料夾中建立一個 **resolvers.js** 檔案,並新增以下程式碼:
const db = require('./db')
const Query = {
//resolver function for greeting
greeting:() => {
return "hello from TutorialsPoint !!!"
},
//resolver function for students returns list
students:() => db.students.list(),
//resolver function for studentbyId
studentById:(root,args,context,info) => {
//args will contain parameter passed in query
return db.students.get(args.id);
}
}
//for each single student object returned,resolver is invoked
const Student = {
fullName:(root,args,context,info) => {
return root.firstName+":"+root.lastName
}
}
module.exports = {Query,Student}
步驟 4 - 執行應用程式
建立一個 **server.js** 檔案。參考“環境搭建”章節中的步驟 8。在終端中執行命令 *npm* start。伺服器將在 9000 埠啟動並執行。在這裡,我們使用 GraphiQL 作為客戶端來測試應用程式。
開啟瀏覽器並輸入 URL **https://:9000/graphiql**。在編輯器中鍵入以下查詢:
{
students{
id
fullName
}
}
查詢的響應如下:
{
"data": {
"students": [
{
"id": "S1001",
"fullName": "Mohtashim:Mohammad"
},
{
"id": "S1002",
"fullName": "Kannan:Sudhakaran"
},
{
"id": "S1003",
"fullName": "Kiran:Panigrahi"
}
]
}
}
建立一個 **server.js** 檔案並新增以下程式碼:
const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const db = require('./db');
const port = 9000;
const app = express();
//loading type definitions from schema file
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
//loading resolvers
const resolvers = require('./resolvers')
//binding schema and resolver
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})
//enabling cross domain calls and form post
app.use(cors(), bodyParser.json());
//enabling routes
const {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
//registering port
app.listen(port, () => console.info(`Server started on port ${port}`));
在終端中執行命令 npm start。伺服器將在 9000 埠啟動並執行。在這裡,我們使用 GraphiQL 作為客戶端來測試應用程式。
開啟瀏覽器並輸入 URL **https://:9000/graphiql**。在編輯器中鍵入以下查詢:
{
students{
id
fullName
}
}
查詢的響應如下:
{
"data": {
"students": [
{
"id": "S1001",
"fullName": "Mohtashim:Mohammad"
},
{
"id": "S1002",
"fullName": "Kannan:Sudhakaran"
},
{
"id": "S1003",
"fullName": "Kiran:Panigrahi"
}
]
}
}
圖示 2 - 巢狀查詢
讓我們建立一個巢狀查詢來獲取學生詳細資訊及其大學詳細資訊。我們將使用同一個專案資料夾。
步驟 1 - 編輯模式 (Schema)
模式檔案已經有了 *student* 欄位。讓我們新增一個 college 欄位並定義其型別。
type College {
id:ID!
name:String
location:String
rating:Float
}
type Student {
id:ID!
firstName:String
lastName:String
fullName:String
college:College
}
步驟 2 - 修改 resolvers.js
我們需要新增如下所示的 college 解析器函式。在這種情況下,將為返回的每個學生物件執行 college 解析器函式。此處的解析器的 root 引數將包含 *student*。
const Student = {
fullName:(root,args,context,info) => {
return root.firstName+":"+root.lastName
},
college:(root) => {
return db.colleges.get(root.collegeId);
}
}
module.exports = {Query,Student}
解析器透過呼叫 college 集合的 get 方法並傳遞 *collegeId* 來返回每個學生的 college。我們透過 *collegeId* 在學生和大學之間建立了關聯關係。
步驟 3 - 測試應用程式
開啟終端視窗並導航到專案資料夾。鍵入命令 -npm start。啟動瀏覽器並輸入 URL **https://:9000/graphiql**。
在 GraphiQL 視窗中輸入以下查詢:
{
students{
id
firstName
college {
id
name
location
rating
}
}
}
查詢的響應如下:
{
"data": {
"students": [
{
"id": "S1001",
"firstName": "Mohtashim",
"college": {
"id": "col-102",
"name": "CUSAT",
"location": "Kerala",
"rating": 4.5
}
},
{
"id": "S1002",
"firstName": "Kannan",
"college": {
"id": "col-101",
"name": "AMU",
"location": "Uttar Pradesh",
"rating": 5
}
},
{
"id": "S1003",
"firstName": "Kiran",
"college": {
"id": "col-101",
"name": "AMU",
"location": "Uttar Pradesh",
"rating": 5
}
}
]
}
}
什麼是查詢變數?
如果查詢有一些要傳遞的動態值,則使用變數來表示這些動態值。因此,客戶端應用程式可以重用該查詢。
圖示
讓我們建立一個簡單的應用程式來理解查詢變數。
步驟 1 - 編輯 Schema 檔案
新增一個 *sayHello* 欄位,該欄位接受一個字串引數並返回一個字串。name 值將在客戶端應用程式中動態變化。
type Query {
sayHello(name:String!):String
}
步驟 2 - 編輯 resolver.js 檔案
新增一個 *sayHello* 解析器,該解析器接受如下引數:
sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`
步驟 3 - 在 GraphiQL 中宣告查詢變數
變數宣告以 $ 加上變數名稱開頭。例如:$myname_Variable。
一旦聲明瞭 $myname_Variable,就必須與命名查詢語法一起使用。查詢 myQuery 獲取字串值並將其傳遞給 sayHello,如下所示:
query myQuery($myname_Variable:String!) {
sayHello(name:$myname_Variable)
}
在 GraphiQL 客戶端的“查詢變數”部分中,將值設定為 $myname_Variable 的 JSON 物件。
{
"myname_Variable": "Mohtashim"
}
以上程式碼的輸出如下:
{
"data": {
"sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
}
}
如何將查詢變數與列舉一起使用
讓我們看看當欄位引數為 **列舉型別** 時如何使用查詢變數。
步驟 1 - 編輯 schema.graphql 檔案
enum ColorType {
RED
BLUE
GREEN
}
type Query {
setFavouriteColor(color:ColorType):String
}
*setFavouriteColor* 函式以列舉作為輸入並返回一個字串值。
步驟 2 - 編輯 resolvers.js 檔案
解析器函式 *setFavouriteColor* 接受 *root* 和 *args*。執行時傳遞給函式的列舉值可以透過 args 引數訪問。
setFavouriteColor:(root,args) => {
return "Your Fav Color is :"+args.color;
}
步驟 3 - 在 GraphiQL 中宣告查詢變數
查詢名為 **query_to_setColor**,它獲取名為 color_variable 的 ColorType 變數。此變數將傳遞給 setFavouriteColor 方法。
query query_to_setColor($color_variable:ColorType) {
setFavouriteColor(color:$color_variable)
}
在 GraphiQL 的查詢變數部分,鍵入以下程式碼:
{
"color_variable":"RED"
}
響應如下所示:
{
"data": {
"setFavouriteColor": "Your Fav Color is: RED"
}
}