如何使用Node.js和Express创建GraphQL服务器

关于如何创建由Node.js和Express驱动的GraphQL服务器的简单教程

首先创建一个新的Node.js项目(如果尚未设置):

npm init --y

此命令创建package.json我们需要处理的文件npm

安装npm软件包expressgraphqlexpress-graphql

npm install express graphql express-graphql

创建一个app.js文件,让我们从初始化表示服务器:

const express = require('express')

const app = express()

app.listen(3000, () => { console.log(‘App listening on port 3000’) })

现在我们添加express-graphql。这是一个中间件,我们将其应用于仅一条路线,/graphql路线:

const express = require('express')
const graphqlHTTP = require('express-graphql')

const app = express()

app.use(’/graphql’, graphqlHTTP())

app.listen(3000, () => { console.log(‘App listening on port 3000’) })

我们必须传递一个包含schema属性,其中必须包含图式定义。

我们必须先定义一个模式!

创建一个schema.js文件,然后我们首先需要graphql,然后使用对象解构语法我们得到了GraphQLSchemaGraphQLObjectTypeGraphQLString我们不久将需要使用的对象:

const graphql = require('graphql')
const { GraphQLSchema, GraphQLObjectType, GraphQLString } = graphql

然后我们通过初始化一个新的定义架构值GraphQLSchema实例,传递包含query财产。此属性是的实例GraphQLObjectType目的:

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    //...
  }),
})

module.exports = schema

在这个新对象中,我们必须指定一个namefields参数。最后一个属性是一个对象,其中包含一组属性,每个属性对应于架构的每个字段。在此示例中,我们设置了hello场地:

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
      hello: {
        type: GraphQLString,
        resolve() {
          return 'world'
        },
      },
    },
  }),
})

resolve()方法返回字符串world,这意味着当我们要求hello字段,我们将返回该字符串。

这是完整的schema.js文件内容:

const graphql = require('graphql')
const { GraphQLSchema, GraphQLObjectType, GraphQLString } = graphql

const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: ‘RootQueryType’, fields: { hello: { type: GraphQLString, resolve() { return ‘world’ }, }, }, }), })

module.exports = schema

现在让我们回到我们的app.js文件。

这就是我们所拥有的:

const express = require('express')
const graphqlHTTP = require('express-graphql')

const app = express()

app.use(’/graphql’, graphqlHTTP())

app.listen(3000, () => { console.log(‘App listening on port 3000’) })

我们现在需要schema.js文件:

const schema = require('./schema.js')

然后将其添加到对象中,然后传递给graphqlHTTP()构造函数:

app.use(
  '/graphql',
  graphqlHTTP({
    schema: schema,
  })
)

好的!

现在,我们可以对其进行测试,看看它是否有效。我们可以用图形语言,这是测试GraphQL API的绝佳工具。

它已经安装并启用,我们需要将另一个属性传递给graphqlHTTP构造函数:

app.use(
  '/graphql',
  graphqlHTTP({
    schema: schema,
    graphiql: true,
  })
)

现在,你跑完之后node app.js,访问http://localhost:3000/graphql使用浏览器的URL,您将看到GraphiQL的运行情况:

您可以通过以下查询来测试第一个API调用:

{
  hello
}

结果如下:

现在让我们构建一个更复杂的架构。

一种具有嵌套类型。

我想到的一个例子是博客文章。

博客文章具有标题,描述以及作者。作者有一个名字。

让我们弄清楚这一点。

首先,我们添加一组帖子和作者:

const posts = [
  {
    title: 'First post',
    description: 'Content of the first post',
    author: 'Flavio',
  },
  {
    title: 'Second post',
    description: 'Content of the second post',
    author: 'Roger',
  },
]

const authors = { Flavio: { name: ‘Flavio’, age: 36, }, Roger: { name: ‘Roger’, age: 7, }, }

这是我们从中获取数据的地方。

Next, we define 3 GraphQLObjectType实例:

  • authorType,它定义了作者数据
  • postType,它定义了发布数据
  • queryType,主要的

让我们从作者开始。作者有名字和年龄。

我们使用GraphQLInt类型,我们必须将其添加到require中:

const { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInt } = graphql

//… const authorType = new GraphQLObjectType({ name: ‘Author’, fields: { name: { type: GraphQLString, }, age: { type: GraphQLInt, }, }, })

接下来是postType。帖子具有标题,描述(两个字符串)和作者。作者类型authorType,我们刚刚定义了它,并且有一个解析器。

我们从source参数,即传递给post对象的参数,然后我们根据该参数查找作者数据。我们退货。

const postType = new GraphQLObjectType({
  name: 'Post',
  fields: {
    title: {
      type: GraphQLString,
    },
    description: {
      type: GraphQLString,
    },
    author: {
      type: authorType,
      resolve: (source, params) => {
        return authors[source.author]
      },
    },
  },
})

请注意,解析程序功能可以是异步的,因此您可以使用async / await从数据库或网络中查找资源。

接下来是queryType,这是我们将添加到架构中的根类型。在其中,我们定义2个字段:

  • post单个博客帖子,由ID标识
  • posts帖子列表

它们都具有解析器功能,可以在posts大批:

const queryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    post: {
      type: postType,
      args: {
        id: { type: GraphQLInt },
      },
      resolve: (source, { id }) => {
        return posts[id]
      },
    },
    posts: {
      type: new GraphQLList(postType),
      resolve: () => {
        return posts
      },
    },
  },
})

注意新GraphQLList类型,我们用它来包装postType表示这是一个清单postType对象。我们必须首先要求它:

const {
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLString,
  GraphQLList,
  GraphQLInt,
} = graphql

而已。我们需要将其添加到我们的schema并设置为:

const schema = new GraphQLSchema({
  query: queryType,
})

这是完整的代码:

const graphql = require('graphql')
const {
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLString,
  GraphQLList,
  GraphQLInt,
} = graphql

const posts = [ { title: ‘First post’, description: ‘Content of the first post’, author: ‘Flavio’, }, { title: ‘Second post’, description: ‘Content of the second post’, author: ‘Roger’, }, ]

const authors = { Flavio: { name: ‘Flavio’, age: 36, }, Roger: { name: ‘Roger’, age: 7, }, }

const authorType = new GraphQLObjectType({ name: ‘Author’, fields: { name: { type: GraphQLString, }, age: { type: GraphQLInt, }, }, })

const postType = new GraphQLObjectType({ name: ‘Post’, fields: { title: { type: GraphQLString, }, description: { type: GraphQLString, }, author: { type: authorType, resolve: (source, params) => { return authors[source.author] }, }, }, })

const queryType = new GraphQLObjectType({ name: ‘Query’, fields: { post: { type: postType, args: { id: { type: GraphQLInt }, }, resolve: (source, { id }) => { return posts[id] }, }, posts: { type: new GraphQLList(postType), resolve: () => { return posts }, }, }, })

const schema = new GraphQLSchema({ query: queryType, })

module.exports = schema

查看有关故障的完整代码


更多graphql教程: