NodeJS/Apollo GraphQL中如何将QueryResolver的字段值传递到其他JS文件
现有代码问题
- 你的
data.js在模块加载时就执行了全表查询,只执行一次,无法响应每次请求的动态ID参数 - 未对外暴露可接收ID参数的查询方法,也没有加SQL过滤逻辑,只能固定取第一条数据
- 数据库查询是异步操作,你之前的同步取值逻辑本身也拿不到动态数据
第一步:修改 models/data.js
把静态查询改为可接收ID参数的异步查询方法,同时用参数化查询避免SQL注入风险:
// 保持你原有数据库连接conn的逻辑不变 var getArticleById = function(articleId) { return new Promise(function(resolve, reject) { // 用?做参数占位符,参数化查询防注入 var query_str = 'SELECT * FROM Artikel WHERE id = ?'; conn.query(query_str, [articleId], function (err, rows, fields) { if (err) { return reject(err); } // 查询结果为空的话返回null,符合GraphQL查询规范 resolve(rows.length ? rows[0] : null); }); }); } module.exports = { getArticleById };
第二步:修改Resolver代码
Resolver改为异步逻辑,调用上面的方法传入用户输入的ID即可:
// 引入data.js导出的方法,路径根据你实际项目结构调整 const { getArticleById } = require('./models/data'); module.exports = { Query: { // 加async标识异步方法 article: async (parent, { id }) => { // 传入ID调用查询方法,await等待异步查询结果 return await getArticleById(id); }, }, Node: { __resolveType(node) { if(node.toObject?.name){ return 'Article'; } } } }
补充说明
重要提醒:不要直接把ID拼接进SQL字符串,必须用参数化查询,避免SQL注入漏洞
- 如果你需要保留全表查询的能力,可以再单独导出全表查询的方法即可,不要在模块加载阶段执行数据库查询
- 如果你的
Article类型字段和数据库返回的字段名不一致(比如数据库里是NAME,GraphQL类型里是title),可以在getArticleById里做字段映射再返回:
// 字段映射示例 resolve(rows.length ? { id: rows[0].id, title: rows[0].NAME } : null);
内容的提问来源于stack exchange,提问作者Nicole Höfler
相关产品推荐
相关产品推荐

