GraphQL LogoGraphQL

传递参数

就像 REST API 一样,在 GraphQL API 中向端点传递参数也很常见。通过在模式语言中定义参数,类型检查会自动进行。每个参数必须命名并具有类型。例如,在 基本类型文档 中,我们有一个名为 rollThreeDice 的端点

type Query {
rollThreeDice: [Int]
}

与其硬编码“three”,我们可能想要一个更通用的函数,它可以掷出 numDice 个骰子,每个骰子有 numSides 个面。我们可以像这样在 GraphQL 模式语言中添加参数

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

Int! 中的感叹号表示 numDice 不能为 null,这意味着我们可以跳过一些验证逻辑,使我们的服务器代码更简单。我们可以让 numSides 为 null,并假设默认情况下骰子有 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 调用。

继续阅读 →对象类型