在联合解析器中,我们可能需要查询多个子服务来获取所需的数据。当其中一个子服务未能找到所需的实体时,我们需要优雅地处理该情况,并且不应该向客户端返回错误。以下是一种解决方案:
假设我们有两个子服务,一个服务用于查询用户,另一个服务用于查询订单。我们需要查询用户的所有订单。
首先,在子服务中定义一个自定义错误类型:
import { ApolloError } from 'apollo-server-errors';
export class UserNotFoundError extends ApolloError {
constructor() {
super('User not found', 'USER_NOT_FOUND');
}
}
然后在联合解析器中使用此错误类型,如下所示:
const resolvers = {
Query: {
user: async (_, { id }, { dataSources }) => {
const userData = await dataSources.userAPI.getUserById(id);
if (!userData) {
throw new UserNotFoundError();
}
return userData;
},
},
User: {
orders: async (user, _, { dataSources }) => {
const orderData = await dataSources.orderAPI.getOrdersByUserId(user.id);
return orderData;
},
},
// ...
};
现在,如果用户未找到,将引发UserNotFoundError
。在根据“User”定义订单解析器时,我们可以使用内容协商机制处理此错误类型:
const { ApolloServer } = require('apollo-server');
const { ApolloError, toApolloError } = require('apollo-server-errors');
const { buildFederatedSchema } = require('@apollo/federation');
const resolvers = {
// ...
User: {
orders: async (user, _, { dataSources }) => {
try {
const orderData = await dataSources.orderAPI.getOrdersByUserId(user.id);
return orderData;
} catch (error) {
if (error instanceof ApolloError) {
throw error;
}
const notFoundError = new UserNotFoundError();
throw toApolloError(notFoundError