"message":"Cannot read properties of undefined (reading 'asyncIterator')",在阿波罗工作室
"message": "Cannot read properties of undefined (reading 'asyncIterator')", in Apollo Studio
我在 Apollo Studio 中提交订阅时收到以下响应,我正在失去理智调试!我似乎找不到问题。
通常在执行 server.installSubscriptionHandlers()
时一切都会正常,但现在在 Apollo 版本 3 中,根据文档,事情必须以不同的方式完成。
在这里阅读更多:https://www.apollographql.com/docs/apollo-server/data/subscriptions/
我的包裹:
"graphql-subscriptions": "^2.0.0",
"graphql-tools": "^4.0.8",
"subscriptions-transport-ws": "^0.11.0",
"apollo-server-express": "^3.5.0",
"express": "^4.17.2",
ApolloStudio 中的响应:
{
"errors": [
{
"message": "Cannot read properties of undefined (reading 'asyncIterator')",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"newTodo"
]
}
]
}
我在 ApolloStudio 中输入的内容:
subscription {
newTodo {
description
id
title
}
}
我的相关解析器代码:
const NEW_TODO = "NEW_TODO";
const resolvers: IResolvers = {
//...
Mutation: {
addTodo: async (
parent,
args: null,
{ pubsub },
info: any
): Promise<Todo> => {
const newTodo: Todo = {
id: v4(),
title: "New Todo!",
description: "New Todo, Wohoo"
}
todos.push(newTodo);
pubsub.publish(NEW_TODO, { newTodo });
return todos[todos.length - 1];
}
},
Subscription: {
newTodo: {
subscribe: (_, __, {pubsub}) => pubsub.asyncIterator(NEW_TODO),
},
}
}
我的类型定义:
type Subscription {
newTodo: Todo!
}
我的服务器:
//...
const pubsub = new PubSub();
const apolloServer = new ApolloServer({
schema,
context: ({req, res}): any => ({req, res, pubsub}),
plugins: [{
serverWillStart: async () => {
return {
async drainServer() {
subscriptionServer.close();
}
}
}
}],
});
(async function() {
await apolloServer.start();
apolloServer.applyMiddleware({ app, cors: true });
})();
const httpServer = createServer(app);
const subscriptionServer = new SubscriptionServer({
schema,
execute,
subscribe,
onConnect() {
console.log("SubscriptionServer ready!");
},
}, {
server: httpServer,
path: "/graphql"
});
//...
正如@Jared Smith 所说,subscribe()
没有接收到 pubsub
存在问题,所以我通过访问服务器代码并将 const pubsub
更改为 export const pubsub
然后我将它导入解析器。似乎是一个不优雅的解决方案,但它现在可以完成工作!
我通过使用 useServer 在 websocket 服务器上设置上下文来解决它,查询和突变似乎与订阅有不同的上下文,这是我的代码
(async () => {
const app = express();
const httpServer = createServer(app);
const pubsub = new PubSub();
app.use(cors());
const schema = makeExecutableSchema({ typeDefs, resolvers});
const wsServer = new WebSocketServer({
server: httpServer,
path: '/graphql',
})
const serverCleanup = useServer({
schema,
context: (ctx, msg, args) => ({ pubsub }), // <-- SOLVES IT
}, wsServer);
const apolloServer = new ApolloServer({
schema,
context: ({ req, res }: any) => ({req, res, pubsub}),
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
{
async serverWillStart() {
return {
async drainServer(){
await serverCleanup.dispose();
},
};
}
},
],
});
await apolloServer.start();
apolloServer.applyMiddleware({ app, cors: false });
httpServer.listen({ port: 8000 }, () => {
console.log(
` Query endpoint ready at http://localhost:8000${apolloServer.graphqlPath}`
);
console.log(
` Subscription endpoint ready at ws://localhost:8000${apolloServer.graphqlPath}`
);
});
})()
我在 Apollo Studio 中提交订阅时收到以下响应,我正在失去理智调试!我似乎找不到问题。
通常在执行 server.installSubscriptionHandlers()
时一切都会正常,但现在在 Apollo 版本 3 中,根据文档,事情必须以不同的方式完成。
在这里阅读更多:https://www.apollographql.com/docs/apollo-server/data/subscriptions/
我的包裹:
"graphql-subscriptions": "^2.0.0",
"graphql-tools": "^4.0.8",
"subscriptions-transport-ws": "^0.11.0",
"apollo-server-express": "^3.5.0",
"express": "^4.17.2",
ApolloStudio 中的响应:
{
"errors": [
{
"message": "Cannot read properties of undefined (reading 'asyncIterator')",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"newTodo"
]
}
]
}
我在 ApolloStudio 中输入的内容:
subscription {
newTodo {
description
id
title
}
}
我的相关解析器代码:
const NEW_TODO = "NEW_TODO";
const resolvers: IResolvers = {
//...
Mutation: {
addTodo: async (
parent,
args: null,
{ pubsub },
info: any
): Promise<Todo> => {
const newTodo: Todo = {
id: v4(),
title: "New Todo!",
description: "New Todo, Wohoo"
}
todos.push(newTodo);
pubsub.publish(NEW_TODO, { newTodo });
return todos[todos.length - 1];
}
},
Subscription: {
newTodo: {
subscribe: (_, __, {pubsub}) => pubsub.asyncIterator(NEW_TODO),
},
}
}
我的类型定义:
type Subscription {
newTodo: Todo!
}
我的服务器:
//...
const pubsub = new PubSub();
const apolloServer = new ApolloServer({
schema,
context: ({req, res}): any => ({req, res, pubsub}),
plugins: [{
serverWillStart: async () => {
return {
async drainServer() {
subscriptionServer.close();
}
}
}
}],
});
(async function() {
await apolloServer.start();
apolloServer.applyMiddleware({ app, cors: true });
})();
const httpServer = createServer(app);
const subscriptionServer = new SubscriptionServer({
schema,
execute,
subscribe,
onConnect() {
console.log("SubscriptionServer ready!");
},
}, {
server: httpServer,
path: "/graphql"
});
//...
正如@Jared Smith 所说,subscribe()
没有接收到 pubsub
存在问题,所以我通过访问服务器代码并将 const pubsub
更改为 export const pubsub
然后我将它导入解析器。似乎是一个不优雅的解决方案,但它现在可以完成工作!
我通过使用 useServer 在 websocket 服务器上设置上下文来解决它,查询和突变似乎与订阅有不同的上下文,这是我的代码
(async () => {
const app = express();
const httpServer = createServer(app);
const pubsub = new PubSub();
app.use(cors());
const schema = makeExecutableSchema({ typeDefs, resolvers});
const wsServer = new WebSocketServer({
server: httpServer,
path: '/graphql',
})
const serverCleanup = useServer({
schema,
context: (ctx, msg, args) => ({ pubsub }), // <-- SOLVES IT
}, wsServer);
const apolloServer = new ApolloServer({
schema,
context: ({ req, res }: any) => ({req, res, pubsub}),
plugins: [
ApolloServerPluginDrainHttpServer({ httpServer }),
{
async serverWillStart() {
return {
async drainServer(){
await serverCleanup.dispose();
},
};
}
},
],
});
await apolloServer.start();
apolloServer.applyMiddleware({ app, cors: false });
httpServer.listen({ port: 8000 }, () => {
console.log(
` Query endpoint ready at http://localhost:8000${apolloServer.graphqlPath}`
);
console.log(
` Subscription endpoint ready at ws://localhost:8000${apolloServer.graphqlPath}`
);
});
})()