如何修复 GraphQL 中继连接的循环依赖
How to fix circular dependency with GraphQL Relay connections
我已经将我的连接分离到它自己的文件中,并且可以在我的根查询中使用它(当在类型中定义连接时它工作正常),但是当试图通过将它导入到类型中来使用它时连接是为了我刚回来:
Error: PageEdge.node field type must be Output Type but got: undefined
我可以让连接在我的 QueryType 中工作,但不能在 PageType 中工作。我的架构大致是这样的。
QueryType {
pages: [PageType]
}
PageType {
_id: string
pages: [PageType]
}
这是一个 link 到项目仓库的 graphql 东西所在的地方(我只是推送了一个提交,它错误地查看了所有代码):
https://github.com/DaveyEdwards/myiworlds/tree/master/src/data
我已经对 QueryType 和 PageType 字段进行了 thunk(似乎可以解决大多数人的问题的解决方案)并且还尝试从接口中进行 thunk:
interfaces: () => [nodeInterface]
我认为对于任何与用户和朋友一起构建应用程序的人来说,这是一个非常普遍的问题。
UserType: {
friends: [UserType]
}
我的页面类型:
import { nodeInterface } from '../nodeInterface';
import PageConnection from './connections/PageConnection';
const PageType = new ObjectType({
name: 'Page',
description: 'Everything you see can be placed inside a page.',
fields: () => ({
id: globalIdField('Page', page => page._id),
_id: {
type: new NonNull(ID),
description: 'A unique id used to instantly locate this page inside the database',
},
pageEdge: {
type: PageConnection,
args: connectionArgs,
resolve: async (page, { args }, { loaders }) => {
if (page.pageEdge) {
const pageEdge = await loaders.pageLoader.loadMany(page.pageEdge);
const connection = connectionFromArray(pageEdge, args);
return connection;
}
},
},
}),
interfaces: () => [nodeInterface],
});
export default PageType;
我的页面连接:
import { connectionDefinitions } from 'graphql-relay';
import PageType from '../PageType';
const { connectionType: PageConnection } = connectionDefinitions({
name: 'Page',
nodeType: PageType,
});
export default PageConnection;
我的节点接口:
import { nodeDefinitions } from 'graphql-relay';
import { getNode, getNodeType } from './type-registry';
export const { nodeInterface, nodeField } = nodeDefinitions(getNode, getNodeType);
我的类型注册表:
import { fromGlobalId } from 'graphql-relay';
require('babel-polyfill');
const types = {};
export const registerType = (model, type, lookupFn) => {
types[type.name] = { model, type, lookupFn };
};
export const getNode = async (globalId) => {
const { type: typeName, id } = fromGlobalId(globalId);
console.log('getNode', globalId, typeName, id);
if (types[typeName]) {
const object1 = await types[typeName].lookupFn(id);
const Class = types[typeName].model;
// let result = Object.create(types[typeName].model, object1);
const result = new Class(object1);
console.log('getNode result', result);
return result;
}
return null;
};
export const getNodeType = (obj) => {
const keys = Object.keys(types);
let ret = null;
keys.map((typeName) => {
if (obj instanceof types[typeName].model) {
ret = types[typeName].type;
}
return true;
});
return ret;
};
导入连接工作的我的 QueryType
import {
GraphQLObjectType as ObjectType,
GraphQLList as List,
GraphQLString as StringType,
} from 'graphql';
import { connectionArgs, connectionFromArray, connectionDefinitions } from 'graphql-relay';
import { nodeField } from '../nodeInterface';
import PageType from './PageType';
import { getPageList } from '../queries/googleDatastore/pageQueries';
import PageConnection from './connections/PageConnection';
const QueryType = new ObjectType({
name: 'QueryType',
fields: () => ({
pages: {
type: PageConnection,
args: connectionArgs,
resolve: async (obj, args) => {
const response = [];
try {
const pageEdge = await getPageList();
const connection = connectionFromArray(pageEdge, args);
return connection;
} catch (err) {
console.log('pages err', err);
}
return response;
},
},
node: nodeField,
}),
});
export default QueryType;
我一直在努力解决这个问题的资源:
这个 repo 的一部分是我首先实现的让连接工作的东西
https://github.com/bondz/learn-graphql-relay/blob/47211fdec44ce4bb10f487bddfc7411e5690b894/src/types/projectConnection.js
Edge.node field type must be Output Type but got: undefined
https://github.com/graphql/graphql-js/issues/612
只需删除 PageType.js
顶部的 import PageConnection
并使用运行时要求:
...
pageEdge: {
type: require('./connections/PageConnection'),
args: connectionArgs,
...
我已经将我的连接分离到它自己的文件中,并且可以在我的根查询中使用它(当在类型中定义连接时它工作正常),但是当试图通过将它导入到类型中来使用它时连接是为了我刚回来:
Error: PageEdge.node field type must be Output Type but got: undefined
我可以让连接在我的 QueryType 中工作,但不能在 PageType 中工作。我的架构大致是这样的。
QueryType {
pages: [PageType]
}
PageType {
_id: string
pages: [PageType]
}
这是一个 link 到项目仓库的 graphql 东西所在的地方(我只是推送了一个提交,它错误地查看了所有代码): https://github.com/DaveyEdwards/myiworlds/tree/master/src/data
我已经对 QueryType 和 PageType 字段进行了 thunk(似乎可以解决大多数人的问题的解决方案)并且还尝试从接口中进行 thunk:
interfaces: () => [nodeInterface]
我认为对于任何与用户和朋友一起构建应用程序的人来说,这是一个非常普遍的问题。
UserType: {
friends: [UserType]
}
我的页面类型:
import { nodeInterface } from '../nodeInterface';
import PageConnection from './connections/PageConnection';
const PageType = new ObjectType({
name: 'Page',
description: 'Everything you see can be placed inside a page.',
fields: () => ({
id: globalIdField('Page', page => page._id),
_id: {
type: new NonNull(ID),
description: 'A unique id used to instantly locate this page inside the database',
},
pageEdge: {
type: PageConnection,
args: connectionArgs,
resolve: async (page, { args }, { loaders }) => {
if (page.pageEdge) {
const pageEdge = await loaders.pageLoader.loadMany(page.pageEdge);
const connection = connectionFromArray(pageEdge, args);
return connection;
}
},
},
}),
interfaces: () => [nodeInterface],
});
export default PageType;
我的页面连接:
import { connectionDefinitions } from 'graphql-relay';
import PageType from '../PageType';
const { connectionType: PageConnection } = connectionDefinitions({
name: 'Page',
nodeType: PageType,
});
export default PageConnection;
我的节点接口:
import { nodeDefinitions } from 'graphql-relay';
import { getNode, getNodeType } from './type-registry';
export const { nodeInterface, nodeField } = nodeDefinitions(getNode, getNodeType);
我的类型注册表:
import { fromGlobalId } from 'graphql-relay';
require('babel-polyfill');
const types = {};
export const registerType = (model, type, lookupFn) => {
types[type.name] = { model, type, lookupFn };
};
export const getNode = async (globalId) => {
const { type: typeName, id } = fromGlobalId(globalId);
console.log('getNode', globalId, typeName, id);
if (types[typeName]) {
const object1 = await types[typeName].lookupFn(id);
const Class = types[typeName].model;
// let result = Object.create(types[typeName].model, object1);
const result = new Class(object1);
console.log('getNode result', result);
return result;
}
return null;
};
export const getNodeType = (obj) => {
const keys = Object.keys(types);
let ret = null;
keys.map((typeName) => {
if (obj instanceof types[typeName].model) {
ret = types[typeName].type;
}
return true;
});
return ret;
};
导入连接工作的我的 QueryType
import {
GraphQLObjectType as ObjectType,
GraphQLList as List,
GraphQLString as StringType,
} from 'graphql';
import { connectionArgs, connectionFromArray, connectionDefinitions } from 'graphql-relay';
import { nodeField } from '../nodeInterface';
import PageType from './PageType';
import { getPageList } from '../queries/googleDatastore/pageQueries';
import PageConnection from './connections/PageConnection';
const QueryType = new ObjectType({
name: 'QueryType',
fields: () => ({
pages: {
type: PageConnection,
args: connectionArgs,
resolve: async (obj, args) => {
const response = [];
try {
const pageEdge = await getPageList();
const connection = connectionFromArray(pageEdge, args);
return connection;
} catch (err) {
console.log('pages err', err);
}
return response;
},
},
node: nodeField,
}),
});
export default QueryType;
我一直在努力解决这个问题的资源:
这个 repo 的一部分是我首先实现的让连接工作的东西 https://github.com/bondz/learn-graphql-relay/blob/47211fdec44ce4bb10f487bddfc7411e5690b894/src/types/projectConnection.js
Edge.node field type must be Output Type but got: undefined
https://github.com/graphql/graphql-js/issues/612
只需删除 PageType.js
顶部的 import PageConnection
并使用运行时要求:
...
pageEdge: {
type: require('./connections/PageConnection'),
args: connectionArgs,
...