【问题标题】:GraphQL how to handle an error message when the response originates from a microservice当响应来自微服务时,GraphQL 如何处理错误消息
【发布时间】:2019-04-04 23:39:34
【问题描述】:

我有一个 API,当传入一个无效的授权令牌时,它的响应如下:

未经授权的回复:

{
   "status": "failure",
   "message": "Unauthorized" 
}

但是当一个有效的令牌被传入时,它会返回一个对象数组,每个对象代表一个文档,如下所示:

授权回复:

[{
    "_id": "5bd8f520e68ba2003ec9f528",
    "user": "5bd8f50cced689002769d254",
    "title": "A title for a document",
    "content": "Some content for a document",
}, { 
    "_id": "5bd8f520e68ba2003ec9f528",
    "user": "5bd8f50cced689002769d254",
    ....
}]

我如何优雅地处理 GraphQL 中的错误响应 源于我的运行快递的微服务?以及如何覆盖响应中数据结构的变化?

我的解析器:

const getDocuments = async context => {
  const config = {
    headers: {
      Authorization: context.token
    }
  };

  try {
    return await axios
      .get("http://document_service:4000/v1/documents", config)
      .then(response => {
        return response.data;
      })
      .catch(error => {
        return error.data;
      });
  } catch (err) {
    return err;
  }
};

const Query = {
  docServiceGetDocs: (obj, args, context) => getDocuments(context)
};

response.data 将返回文档数组或带有状态和消息的对象。

我的架构:

type getDocuments {
  _id: String
  user: String
  title: String
  content: String
}

type Query {
  docServiceGetDocs: [getDocuments]
}

[getDocuments] 我想这需要一个对象数组,但不确定如果我将未经授权的响应作为对象处理。

我正在使用阿波罗服务器 2

【问题讨论】:

    标签: node.js express error-handling graphql


    【解决方案1】:

    理想情况下,如果使用内容响应而不是状态代码来传达错误,那么无论状态如何,API 的响应都会具有某种一致的形状。

    {
       "status": "failure",
       "message": "Unauthorized",
       "response": []
    }
    
    {
       "status": "success",
       "message": "",
       "response": [{ user: "Dan" }],
    }
    

    但如果这不容易解决,您只需检查解析器内的响应形状即可:

    const getDocuments = async context => {
      const config = {
        headers: {
          Authorization: context.token
        }
      };
    
      try {
        const response = await axios.get("http://document_service:4000/v1/documents", config)
        const data = response.data
        if (data && data.status === 'failure') {
          throw new Error(data.message)
        }
        return data
      } catch (err) {
        // example of how to handle axios errors
    
        let message = ''
        if (err.response) {
          // Status code out of the range of 2xx, format error message according
        } else if (err.request) {
          // The request was made but no response was received, format message accordingly
        } else {
          message = err.message
        }
        // throw whatever error you have so it's included in your graphql response
        throw new Error(message) 
      }
    };
    

    【讨论】:

      猜你喜欢
      • 2012-04-08
      • 1970-01-01
      • 2016-03-27
      • 2014-03-19
      • 2019-09-19
      • 2019-12-31
      • 2020-05-09
      • 2020-03-18
      • 2017-07-23
      相关资源
      最近更新 更多