就像 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 languagevar schema = buildSchema(` type Query { rollDice(numDice: Int!, numSides: Int): [Int] }`)
// The root provides a resolver function for each API endpointvar 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 = 3var sides = 6var 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 呼叫。