对于许多应用程序,您可以在应用程序启动时定义一个固定模式,并使用 GraphQL 模式语言来定义它。在某些情况下,以编程方式构建模式很有用。您可以使用 GraphQLSchema 构造函数来完成此操作。
当您使用 GraphQLSchema 构造函数创建模式时,您不是仅使用模式语言来定义 Query 和 Mutation 类型,而是将它们创建为单独的对象类型。
例如,假设我们正在构建一个简单的 API,它允许您根据 ID 获取几个硬编码用户的用户数据。使用 buildSchema,我们可以编写一个带有以下内容的服务器:
var express = require("express")var { createHandler } = require("graphql-http/lib/use/express")var { buildSchema } = require("graphql")
var schema = buildSchema(`  type User {    id: String    name: String  }
  type Query {    user(id: String): User  }`)
// Maps id to User objectvar fakeDatabase = {  a: {    id: "a",    name: "alice",  },  b: {    id: "b",    name: "bob",  },}
var root = {  user: ({ id }) => {    return fakeDatabase[id]  },}
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 模式语言
var express = require("express")var { createHandler } = require("graphql-http/lib/use/express")var graphql = require("graphql")
// Maps id to User objectvar fakeDatabase = {  a: {    id: "a",    name: "alice",  },  b: {    id: "b",    name: "bob",  },}
// Define the User typevar userType = new graphql.GraphQLObjectType({  name: "User",  fields: {    id: { type: graphql.GraphQLString },    name: { type: graphql.GraphQLString },  },})
// Define the Query typevar queryType = new graphql.GraphQLObjectType({  name: "Query",  fields: {    user: {      type: userType,      // `args` describes the arguments that the `user` query accepts      args: {        id: { type: graphql.GraphQLString },      },      resolve: (_, { id }) => {        return fakeDatabase[id]      },    },  },})
var schema = new graphql.GraphQLSchema({ query: queryType })
var app = express()app.all(  "/graphql",  createHandler({    schema: schema,  }))app.listen(4000)console.log("Running a GraphQL API server at localhost:4000/graphql")
当我们使用这种方法创建 API 时,根级解析器是在 Query 和 Mutation 类型上实现的,而不是在 root 对象上实现的。
如果您想从其他内容(如数据库模式)自动创建 GraphQL 模式,这将特别有用。您可能有一个用于创建和更新数据库记录的通用格式。这对于实现诸如联合类型之类的功能也很有用,这些功能无法干净地映射到 ES6 类和模式语言。