GraphQL 是一种用于 API 构建的查询语言,它由 Facebook 开发并开源。它提供了一种更为高效的方式来描述和请求数据。在前端开发中,GraphQL 正逐渐成为前端与后端开发团队之间的传统 REST API 的替代方案。
Hapi 是 Node.js 中最受欢迎的 Web 框架之一。它的独特之处在于其插件体系结构和良好的编写 API 的能力。在本文中,我们将介绍如何在 Hapi 框架中构建 GraphQL API。
准备工作
在开始之前,请确保您已经安装了 Node.js 和 npm 并在本地环境中安装了 Hapi 框架。
接下来,我们需要安装一些软件包:
npm install graphql apollo-server-hapi hapi-graceful-shutdown
graphql
: 这个包是一个用于构建 GraphQL API 的标准基础库。apollo-server-hapi
: 这个包是一个 Apollo GraphQL Server 与 Hapi 框架的连接器。hapi-graceful-shutdown
: 这个包是一个用于优雅地关闭 Hapi 服务器的插件。
构建 GraphQL API
构建 GraphQL API 需要定义两个部分:类型和解析器。
我们将定义下面 3 个类型:
ToyType
: 这个类型用于定义玩具模型的结构。Query
: 这个类型用于定义我们可以查询的内容。Mutation
: 这个类型用于定义我们可以更改的内容。
定义类型:
// javascriptcn.com 代码示例 const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLNonNull, GraphQLList, } = require('graphql'); const ToyType = new GraphQLObjectType({ name: 'Toy', fields: () => ({ id: { type: GraphQLNonNull(GraphQLInt) }, name: { type: GraphQLNonNull(GraphQLString) }, description: { type: GraphQLNonNull(GraphQLString) }, age: { type: GraphQLNonNull(GraphQLInt) }, }), }); const Query = new GraphQLObjectType({ name: 'Query', fields: () => ({ getToyById: { type: ToyType, args: { id: { type: GraphQLNonNull(GraphQLInt) } }, resolve: async (parent, args) => { const connection = await knex.raw(`SELECT * FROM toys WHERE id = ${args.id}`); return connection.rows[0]; }, }, getToys: { type: new GraphQLList(ToyType), resolve: async () => { const connection = await knex.raw(`SELECT * FROM toys`); return connection.rows; }, }, }), }); const Mutation = new GraphQLObjectType({ name: 'Mutation', fields: () => ({ createToy: { type: ToyType, args: { name: { type: GraphQLNonNull(GraphQLString) }, description: { type: GraphQLNonNull(GraphQLString) }, age: { type: GraphQLNonNull(GraphQLInt) }, }, resolve: async (parent, args) => { const connection = await knex('toys').insert({ name: args.name, description: args.description, age: args.age, }); return { id: connection[0], ...args, } }, }, deleteToyById: { type: ToyType, args: { id: { type: GraphQLNonNull(GraphQLInt) } }, resolve: async (parent, args) => { await knex('toys').where({ id: args.id }).del(); return { id: args.id }; }, }, updateToyById: { type: ToyType, args: { id: { type: GraphQLNonNull(GraphQLInt) }, name: { type: GraphQLNonNull(GraphQLString) }, description: { type: GraphQLNonNull(GraphQLString) }, age: { type: GraphQLNonNull(GraphQLInt) }, }, resolve: async (parent, args) => { await knex('toys').where({ id: args.id }).update(args); return args; }, }, }), });
定义了类型之后,我们需要定义查询和修改类型的解析器:
// javascriptcn.com 代码示例 const resolvers = { Query: { getToyById: (_, args) => knex.raw(`SELECT * FROM toys WHERE id = ${args.id}`) .then(res => res.rows[0]), getToys: () => knex.raw(`SELECT * FROM toys`).then(res => res.rows), }, Mutation: { createToy: (_, args) => knex('toys') .insert(args) .returning('*') .then(res => res[0]), deleteToyById: (_, args) => knex('toys') .where('id', args.id) .del() .then(() => ({ id: args.id })), updateToyById: (_, args) => knex('toys') .where('id', args.id) .update(args) .then(() => args), }, };
最后,我们需要将 Hapi 服务器与 Apollo 连接起来:
// javascriptcn.com 代码示例 const Hapi = require('@hapi/hapi'); const { ApolloServer } = require('apollo-server-hapi'); const { graphqlHapi } = require('apollo-server-hapi'); const { mergeSchemas } = require('graphql-tools'); const { shutdown: gracefulShutdown } = require('hapi-graceful-shutdown'); const server = Hapi.server({ port: 3000, host: 'localhost', }); const apolloServer = new ApolloServer({ typeDefs, resolvers, introspection: true, }); const startServer = async () => { await apolloServer.start(); await server.register({ plugin: graphqlHapi, options: { path: '/graphql', graphqlOptions: { schema: apolloServer.schema, introspection: true, formatError: (error) => { console.log(error); return error; }, }, route: { cors: true, }, }, }); await server.start(); } startServer().then(() => { gracefulShutdown(server); console.log(`Server running at: ${server.info.uri}`); }).catch((err) => { console.log(err); process.exit(1); });
我们完成了 Hapi 和 GraphQL 的集成。现在你可以通过访问 http://localhost:3000/graphql
来测试 GraphQL API。
总结
本文中,我们介绍了如何使用 Hapi 框架构建 GraphQL API,我们定义了几个类型和解析器,然后将 Hapi 服务器连接起来。现在,您应该已经了解了如何使用 Hapi 框架构建 GraphQL API,希望这篇文章对您有所启发。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6548b10b7d4982a6eb2f63f5