返回

Egg.js 中 GraphQL 玩转新体验

前端

前言

在现代 Web 开发中,构建 RESTful API 已经成为主流方式。然而,随着业务的不断发展,RESTful API 也逐渐暴露了一些局限性,例如数据查询不够灵活、资源表示不够直观等。GraphQL 作为一种新型的数据查询语言,可以很好地解决这些问题,因此在近几年备受关注。

Egg.js 简介

Egg.js 是一个基于 Koa 2 的 Node.js 框架,它集成了多种流行的中间件,并提供了一套完善的开发工具,可以帮助开发人员快速构建出高质量的 Web 应用。Egg.js 也支持 GraphQL,并且提供了非常友好的支持,使得开发人员可以轻松地将 GraphQL 集成到自己的项目中。

Egg.js 中使用 GraphQL

在 Egg.js 中使用 GraphQL 非常简单,只需要安装 egg-graphql 插件,然后在项目中创建一个 graphql 目录,并在该目录下创建 schema.graphqlresolver.js 文件即可。

1. 创建 schema.graphql 文件

schema.graphql 文件是 GraphQL 的模式定义文件,它定义了 GraphQL 的数据类型、查询和变异。

# 定义一个名为 `User` 的数据类型
type User {
  id: ID! # ID 字段为必填
  name: String! # 姓名字段为必填
  age: Int # 年龄字段为可选
}

# 定义一个名为 `Query` 的查询类型
type Query {
  # 定义一个名为 `users` 的查询,返回所有用户
  users: [User!]! # 返回值是一个非空的用户数组

  # 定义一个名为 `user` 的查询,返回指定 ID 的用户
  user(id: ID!): User # 返回值是一个用户
}

# 定义一个名为 `Mutation` 的变异类型
type Mutation {
  # 定义一个名为 `createUser` 的变异,创建一个新用户
  createUser(name: String!, age: Int): User! # 返回值是一个非空的用户

  # 定义一个名为 `updateUser` 的变异,更新指定 ID 的用户
  updateUser(id: ID!, name: String, age: Int): User # 返回值是一个用户

  # 定义一个名为 `deleteUser` 的变异,删除指定 ID 的用户
  deleteUser(id: ID!): Boolean! # 返回值是一个布尔值,表示是否删除成功
}

2. 创建 resolver.js 文件

resolver.js 文件是 GraphQL 的解析器文件,它负责将 GraphQL 的查询和变异映射到实际的数据源。

const {GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLList, GraphQLID, GraphQLNonNull} = require('graphql');
const {Sequelize} = require('sequelize');

// 定义 `User` 数据类型的解析器
const UserType = new GraphQLObjectType({
  name: 'User',
  fields: {
    id: {type: GraphQLID},
    name: {type: GraphQLNonNull(GraphQLString)},
    age: {type: GraphQLInt},
  }
});

// 定义 `Query` 查询类型的解析器
const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    users: {
      type: new GraphQLList(UserType),
      resolve: async () => {
        // 从数据库中查询所有用户
        const users = await User.findAll();
        return users;
      }
    },
    user: {
      type: UserType,
      args: {
        id: {type: GraphQLNonNull(GraphQLID)}
      },
      resolve: async (source, args) => {
        // 从数据库中查询指定 ID 的用户
        const user = await User.findByPk(args.id);
        return user;
      }
    },
  }
});

// 定义 `Mutation` 变异类型的解析器
const MutationType = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    createUser: {
      type: UserType,
      args: {
        name: {type: GraphQLNonNull(GraphQLString)},
        age: {type: GraphQLInt},
      },
      resolve: async (source, args) => {
        // 在数据库中创建新用户
        const user = await User.create({
          name: args.name,
          age: args.age,
        });
        return user;
      }
    },
    updateUser: {
      type: UserType,
      args: {
        id: {type: GraphQLNonNull(GraphQLID)},
        name: {type: GraphQLString},
        age: {type: GraphQLInt},
      },
      resolve: async (source, args) => {
        // 更新数据库中指定 ID 的用户
        const user = await User.findByPk(args.id);
        if (user) {
          await user.update({
            name: args.name,
            age: args.age,
          });
          return user;
        } else {
          throw new Error('User not found');
        }
      }
    },
    deleteUser: {
      type: GraphQLNonNull(GraphQLBoolean),
      args: {
        id: {type: GraphQLNonNull(GraphQLID)}
      },
      resolve: async (source, args) => {
        // 从数据库中删除指定 ID 的用户
        const user = await User.findByPk(args.id);
        if (user) {
          await user.destroy();
          return true;
        } else {
          throw new Error('User not found');
        }
      }
    },
  }
});

module.exports = {
  QueryType,
  MutationType,
};

3. 在 Egg.js 应用中注册 GraphQL 服务

在 Egg.js 应用的 config/plugin.js 文件中,注册 egg-graphql 插件并配置 GraphQL 服务。

module.exports = {
  // ... 其他配置
  graphql: {
    router: '/graphql', // GraphQL 服务的路由
    // 其他配置
  }
};

4. 启动 Egg.js 应用

运行 npm start 命令启动 Egg.js 应用,即可访问 GraphQL 服务。

结语

通过上述步骤,我们可以在 Egg.js 中轻松地集成 GraphQL 服务。GraphQL 作为一种新型的数据查询语言,可以帮助我们构建出更灵活、更高效的 RESTful API。如果您正在使用 Egg.js 开发 Web 应用,那么强烈推荐您尝试使用 GraphQL。