如何使用Apollo Server 2.0 GraphQL将架构指令中的信息作为返回数据包括在内?

问题描述 投票:1回答:1

我正在使用架构指令进行字段授权。解析程序返回后,Apollo服务器将调用指令。因此,这些指令无法访问输出,因此当授权失败时,如果没有复杂的解决方法抛出错误,我将无法为用户提供相关信息,最终无论查询是否请求,都将始终返回错误数据。] >

我希望有人比我更了解Apollo的内部,并指出可以在指令中插入适当的信息,因此我不必破坏GraphQL的标准功能。

我尝试在上下文中包括我的输出,但是尽管该指令具有访问权限,但该操作不起作用,因为解析器已经返回了数据,此后不需要上下文版本。

目前,我在指令中使用代码DIRECTIVE_ERROR抛出了一个自定义错误,并包含了我想返回给用户的消息。在formatResponse函数中,我查找指令错误并通过将错误数组转移到数据的内部错误数组中来过滤错误数组。我知道formatResponse并不是要修改数据的内容,但是据我所知,这是我唯一可以访问所需内容的地方。同样令人沮丧的是,响应中的错误对象没有包含错误中的所有字段。

type User implements Node {
  id: ID!
  email: String @requireRole(requires: "error")
}

type UserError implements Error {
  path: [String!]!
  message: String!
}

type UserPayload implements Payload {
  isSuccess: Boolean!
  errors: [UserError]
  data: User
}

type UserOutput implements Output {
  isSuccess: Boolean!
  payload: [UserPayload]
}

/**
 * All output responses should be of format:
 * {
 *  isSuccess: Boolean
 *  payload: {
 *    isSuccess: Boolean
 *    errors: {
 *      path: [String]
 *      message: String
 *    }
 *    data: [{Any}]
 *  }
 * }
 */
const formatResponse = response => {
  if (response.errors) {
    response.errors = response.errors.filter(error => {
      // if error is from a directive, extract into errors
      if (error.extensions.code === "DIRECTIVE_ERROR") {
        const path = error.path;
        const resolverKey = path[0];
        const payloadIndex = path[2];

        // protect from null
        if (response.data[resolverKey] == null) {
          response.data[resolverKey] = {
            isSuccess: false,
            payload: [{ isSuccess: false, errors: [], data: null }]
          };
        } else if (
          response.data[resolverKey].payload[payloadIndex].errors == null
        ) {
          response.data[resolverKey].payload[payloadIndex].errors = [];
        }

        // push error into data errors array
        response.data[resolverKey].payload[payloadIndex].errors.push({
          path: [path[path.length - 1]],
          message: error.message,
          __typename: "DirectiveError"
        });
      } else {
        return error;
      }
    });

    if (response.errors.length === 0) {
      return { data: response.data };
    }
  }

  return response;
};

我对Apollo中操作顺序的理解是:

解析器返回数据根据查询参数过滤数据?在应用的对象/字段上调用指令根据查询参数过滤数据?formatResponse有机会修改输出formatError有机会修改错误返回客户

我想要的是不必在指令中引发错误,以便通过在formatResponse中提取信息来创建传递给用户的信息。预期结果是客户端仅接收其请求的字段,但是当前方法将其中断,并返回数据错误和所有字段,无论客户端是否请求它们。

我正在使用架构指令进行字段授权。解析程序返回后,Apollo服务器将调用指令。因此,伪指令无法访问输出,因此当...

error-handling graphql apollo-server
1个回答
0
投票

您可以使用destruct注入它:

© www.soinside.com 2019 - 2024. All rights reserved.