egg.js连接graphql

一、安装egg-graphql  mysql2 egg-sequelize graphql dataloader

 "dataloader": "^2.0.0",
    "egg": "^2.15.1",
    "egg-graphql": "^2.8.0",
    "egg-scripts": "^2.11.0",
    "egg-sequelize": "^5.2.2",
    "egg-validate": "^2.0.2",
    "graphql": "^14.7.0",
    "lodash": "^4.17.19",
    "mysql2": "^2.1.0"
// config.default.js
const userConfig = {
        myAppName: 'egg-customizescreen',
        sequelize: {
            dialect: 'mysql',
            database: 'graphql', // 数据库名称
            host: 'localhost',
            port: '3306',
            username: 'root',
            password: 'root',
        },
        proxyworker: {
            port: 10086,
        },
        router: '/graphql',
        // 路径 建议命名为graphql
        middleware: ['graphql'],
        // graphQL 路由前的拦截器
        onPreGraphQL: function* (ctx) {},
        // 开发工具 graphiQL 路由前的拦截器,建议用于做权限操作(如只提供开发者使用)
        onPreGraphiQL: function* (ctx) {},
        security: {
            csrf: {
                ignore: () => true,
            },
        }
    };
// plugin.js
'use strict';

/** @type Egg.EggPlugin */
module.exports = {
    // had enabled by egg
    // static: {
    //   enable: true,
    // }
    // 数据库连接
    sequelize: {
        enable: true,
        package: 'egg-sequelize',
    },
    // graphql连接
    graphql: {
        enable: true,
        package: 'egg-graphql',
    },
    // 数据验证
    validate : {
        package: 'egg-validate',
    }
};

二、参考https://zhuanlan.zhihu.com/p/30604868

  • 1、在app目录下创建model、graphql目录

  • 2、model --》user.js
'use strict';

module.exports = (app) => {
    const {STRING} = app.Sequelize;

    const User = app.model.define('user', {
        name: STRING(30),
        password: STRING(32),
    });
    // User.create({
    //     name: 'alice123',
    //     password: '666666',
    //     created_at: new Date(),
    //     updated_at: new Date(),
    // });
    return User;
};
  • 3、query --》schema.graphql
type User {
  id: ID!
  name: String!
  password: String!
}

  • 4、graphql =》user =》connector.js
'use strict';
const DataLoader = require('dataloader');

class UserConnector {
    constructor(ctx) {
        this.ctx = ctx;
        this.loader = new DataLoader(this.fetch.bind(this));
    }

    /**
     * DataLoader缓存数据
     * @param ids
     * @returns {Promise.<*[]>}
     */
    fetch(ids) {
        const users = this.ctx.app.model.User.findAll({
            where: {
                id: ids,
            },
        });
        return users;
    }

    /**
     * 查询多个用户信息
     * @param ids
     * @returns {Promise.<Array.<V|Error>>|Promise<Array<Error | V>>}
     */
    fetchByIds(ids) {
        return this.loader.loadMany(ids);
    }

    /**
     * 查询所有
     * @returns {*}
     */
    fetchList() {
        const users = this.ctx.app.model.User.findAll();
        return users;
    }

    /**
     * 查询单个
     * @param id
     * @returns {Promise<V> | Promise.<V>}
     */
    fetchById(id) {
        return this.loader.load(id);
    }
}

module.exports = UserConnector;

  • 5、graphql =》user =》resolver.js
'use strict';

module.exports = {
    Query: {
        // 查询单个用户
        user(root, {id}, ctx) {
            return ctx.connector.user.fetchById(id);
        },
        // 查询多个用户
        users(root, {id}, ctx) {
            return ctx.connector.user.fetchByIds(id);
        },
        // 查询所有用户
        userList(root, {id}, ctx) {
            return ctx.connector.user.fetchList();
        }
    },
};

  • 6、graphql =》user =》schema.graphql
type Query {
  user(id: ID!): User
  users(id: [ID!]): [User]
  userList: [User]
}

如果报这个错误:TypeError: DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.

 是因为dataloader的版本升级修改实现,查询结果为空时需要处理下

将查询语句修改为,

fetch(ids) {
        const users = this.ctx.app.model.User.findAll({
            where: {
                id: ids,
            },
        });
        return new Promise((resolve, reject) => {
            users.then(res => {
                res.length ? resolve(res) : resolve([{}]);
            })
        })
    }

如果报错:Must provide Source. Received: undefined. at devAssert 请参考https://blog.csdn.net/ligaoming_123/article/details/107905216

  • 7、使用sequelize-cli建表

具体步骤请参考官网https://eggjs.org/zh-cn/tutorials/sequelize.html#%E5%88%9D%E5%A7%8B%E5%8C%96%E9%A1%B9%E7%9B%AE

请注意,建的数据表要比model加一个s复数形式

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值