GraphQL LogoGraphQL

傳遞參數

就像 REST API 一樣,在 GraphQL API 中將參數傳遞至端點是很常見的。透過在架構語言中定義參數,類型檢查會自動進行。每個參數都必須命名並具有類型。例如,在 基本類型文件 中,我們有一個名為 rollThreeDice 的端點

type Query {
rollThreeDice: [Int]
}

我們可能不想要硬編碼「三個」,而是想要一個更通用的函數,用於擲 numDice 個骰子,每個骰子有 numSides 個面。我們可以像這樣將參數新增至 GraphQL 架構語言

type Query {
rollDice(numDice: Int!, numSides: Int): [Int]
}

Int! 中的驚嘆號表示 numDice 不能為空值,這表示我們可以跳過一些驗證邏輯,讓我們的伺服器程式碼更簡單。我們可以讓 numSides 為空值,並假設骰子預設有 6 個面。

到目前為止,我們的解析器函數沒有帶任何參數。當解析器帶有參數時,它們會作為一個「args」物件傳遞,作為函數的第一個參數。因此,rollDice 可以實作為

var root = {
rollDice: args => {
var output = []
for (var i = 0; i < args.numDice; i++) {
output.push(1 + Math.floor(Math.random() * (args.numSides || 6)))
}
return output
},
}

對於這些參數,使用 ES6 解構賦值 很方便,因為您知道它們的格式。因此,我們也可以將 rollDice 寫成

var root = {
rollDice: ({ numDice, numSides }) => {
var output = []
for (var i = 0; i < numDice; i++) {
output.push(1 + Math.floor(Math.random() * (numSides || 6)))
}
return output
},
}

如果您熟悉解構,這會好一點,因為定義 rollDice 的程式碼行會告訴您參數是什麼。

主機此 rollDice API 的伺服器的完整程式碼為

var express = require("express")
var { createHandler } = require("graphql-http/lib/use/express")
var { buildSchema } = require("graphql")
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
type Query {
rollDice(numDice: Int!, numSides: Int): [Int]
}
`)
// The root provides a resolver function for each API endpoint
var root = {
rollDice: ({ numDice, numSides }) => {
var output = []
for (var i = 0; i < numDice; i++) {
output.push(1 + Math.floor(Math.random() * (numSides || 6)))
}
return output
},
}
var app = express()
app.all(
"/graphql",
createHandler({
schema: schema,
rootValue: root,
})
)
app.listen(4000)
console.log("Running a GraphQL API server at localhost:4000/graphql")

當您呼叫此 API 時,您必須按名稱傳遞每個引數。因此,對於上述伺服器,您可以發出此 GraphQL 查詢來擲出三個六面骰子

{
rollDice(numDice: 3, numSides: 6)
}

如果您使用 node server.js 執行此程式碼並瀏覽至 http://localhost:4000/graphql,您可以試用此 API。

當您在程式碼中傳遞引數時,通常最好避免自己建構整個查詢字串。相反地,您可以使用 $ 語法在查詢中定義變數,並將變數作為一個獨立的對應傳遞。

例如,呼叫我們上述伺服器的 JavaScript 程式碼為

var dice = 3
var sides = 6
var query = `query RollDice($dice: Int!, $sides: Int) {
rollDice(numDice: $dice, numSides: $sides)
}`
fetch("/graphql", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
query,
variables: { dice, sides },
}),
})
.then(r => r.json())
.then(data => console.log("data returned:", data))

在 GraphQL 中使用 $dice$sides 作為變數表示我們不必擔心在用戶端進行跳脫。

使用基本類型和引數傳遞,您可以實作 REST API 中可以實作的任何內容。但 GraphQL 支援更強大的查詢。如果您瞭解如何 定義您自己的物件類型,您可以使用單一 API 呼叫取代多個 API 呼叫。

繼續閱讀 →物件類型