就像 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 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 调用。