我如何错误地使用 apollo combineResolvers()?

Posted

技术标签:

【中文标题】我如何错误地使用 apollo combineResolvers()?【英文标题】:How am I using apollo combineResolvers() wrong? 【发布时间】:2021-03-15 10:31:14 【问题描述】:

我正在关注Udemy course on apollo,并且对 nodeJS 也相当陌生。到目前为止,这门课程进展顺利,但在他们从 graphql-resolvers 模块中引入 combineResolvers() 的一步中,有些事情发生了变化。

它正在尝试通过使用来自 graphql-resolvers 模块的 combineResolvers() 向解析器添加身份验证步骤。每个部分独立工作正常,这意味着 isAuthenticated() 本身工作正常,以及通过 user.id 获取用户的用户查询。

当我使用 combineResolvers() 时,我得到一个 INTERNAL_SERVER_ERROR,“错误:不能为不可为空的字段 User.id 返回 null。”。此外,当我收到此错误时,来自 isAuthenticated() 的 console.log 会与一封电子邮件一起显示,因此它应该返回/跳过,但来自用户解析器的 console.log 在 users.find... 之前是不是。他们之间是如何失败的?

这里是相关代码。注释行是在引入 combineResolvers 之前起作用的行:

const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const  combineResolvers  = require('graphql-resolvers');

const  users, tasks  = require('../constants');
const User = require('../database/models/user');
const  isAuthenticated  = require('./middleware');

module.exports = 
    Query: 
        users: () => 
            return users;
        , 
        // user: ( _, args,  email ) => 
        //     console.log("===", email);
        //     return users.find(user => user.id == args.id);
        // 
        user: combineResolvers(isAuthenticated, ( _,  id ,  email ) => 
            console.log("===", email);
            return users.find(user => user.id == id);
        )
    

这里是 isAuthenticated 模块,来自 /resolvers/middleware/index.js:

const skip = require('graphql-resolvers');

module.exports.isAuthenticated = (_, __,  email ) => 
    console.log("isAuthenticated...email : ", email);
    if (!email) 
        throw new Error("Access Denied! Please login to continue");
    
    return skip;

【问题讨论】:

【参考方案1】:

您可以在导出之前定义组合解析器(如在文档中,没有真正的变化,两种方法都应该有效)...

...但您可能需要将async/await 用于与数据库/数据源相关的解析器:

const authedUserById = combineResolvers(
  isAuthenticated, 
  async ( _,  id ,  email ) => 
        console.log("==>>", id, email);
        return await users.find(user => user.id == id);
  
)

module.exports = 
  Query: 
    users: () => 
        return users;
    , 
    user: authedUserById
  

记录了什么id???怎么测试的?变量如何传递?

【讨论】:

为什么要重新定义 combineResolvers?它是从 graphql-resolvers 包中解构出来的。 这里没有重新定义,只有在将它分配给(prop)类型之前'实例化'组合解析器 已更新,记录了什么“id”值??为什么不使用“更现代”export constimport ... 编译器配置/问题? 我试过这个;与原始代码发生了同样的事情,它没有记录“==>>”,所以它甚至没有进入那个方法; “错误:不能为不可为空的字段 User.id 返回 null。”似乎表明 isAuthenticated 方法正在返回一个空的用户,而不是移动到下一个解析器 它不应该,只抛出或未定义...节点版本??? ... 在 isAuthed 中插入更多记录器 .... 从 github.com/lucasconstantino/graphql-resolvers/blob/master/src/… 复制 combineResolvers 函数源(而不是 import/require)并检查它是否有效,然后更改代码以插入一些日志记录

以上是关于我如何错误地使用 apollo combineResolvers()?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将变量传递给 apollo useQuery?

NextJS/Typescript/Apollo 错误;类型上不存在属性

如何使用 React-Apollo 处理 GraphQL 错误?

如何防止我的 Apollo 客户端错误处理程序(onError,错误链接)因同一错误被调用两次?

如何使用 apollo 客户端在 graphql 的角度处理错误?

如何将 apollo 查询数据放入受控输入?