如何在没有循环依赖的情况下在GraphQL中拆分模式
How to split schema in GraphQL without having circular dependencies?
我的问题类似于GraphQL代码中的Javascript循环依赖,但我的问题不在于结构和数据库级别,而在于Javascript (ES6)。
我的模式定义变得太大了,但我不知道在哪里可以将文件分成几个部分。根据不同的对象类型进行切割似乎是合乎逻辑的,但这带来了类似于这个非常简化的,不工作的示例的循环依赖:
// -- file A.js
import { bConnection, getBs } from 'B';
export class A { /*...*/ };
export var getA = (a) => { /*...*/ };
export var getAs = (array_of_as) => { /*...*/ };
export var aType = new GraphQLObjectType ({
name: 'A',
fields: () => ({
bs: {
type: bConnection,
/*...*/
},
resolve: (a, args) => connectionFromPromisedArray (
getBs (a.bs)
),
/*...*/
}),
interfaces: () => [ require ('./nodeDefs').nodeInterface ],
/*...*/
})
export var {
connectionType: aConnection,
edgeType: aEdge
} = connectionDefinitions ({
name: 'A',
nodeType: aType
});
// -- file B.js
import { aConnection, getAs } from 'A';
export class B { /*...*/ };
export var getB = (b) => { /*...*/ };
export var getBs = (array_of_bs) => { /*...*/ };
export var bType = new GraphQLObjectType ({
name: 'B',
fields: () => ({
as: {
type: aConnection,
/*...*/
},
resolve: (b, args) => connectionFromPromisedArray (
getAs (b.bs)
),
/*...*/
}),
interfaces: () => [ require ('./nodeDefs').nodeInterface ],
/*...*/
})
export var {
connectionType: bConnection,
edgeType: bEdge
} = connectionDefinitions ({
name: 'B',
nodeType: bType
});
// -- file nodeDefs.js
import {
fromGlobalId,
nodeDefinitions,
} from 'graphql-relay';
import { A, getA, aType } from 'A'
import { B, getB, bType } from 'B'
export var {nodeInterface, nodeField} = nodeDefinitions (
(globalId) => {
var {type, id} = fromGlobalId (globalId);
if (type === 'A') {
return getA (id);
} else if (type === 'B') {
return getB (id);
}
},
(obj) => {
if (obj instanceof A) {
return aType;
} else if (obj instanceof B) {
return bType;
}
}
)
// -- file schema.js
import {
GraphQLObjectType,
GraphQLSchema,
} from 'graphql';
import { nodeField } from './nodeDefs';
var queryType = new GraphQLObjectType ({
name: 'Query',
fields: () => ({
node: nodeField,
/*...*/
}),
});
是否有通用的方法或最佳实践?
我也有同样的问题。我认为更干净的解决方案是使用gruntjs concat。
grunt.initConfig({
concat: {
js: {
src: ['lib/before.js', 'lib/*', 'lib/after.js'],
dest: 'schema.js',
}
}
});
使用此配置,您可以将模式拆分为几个文件,创建最终的schema.js。
before.js可以这样写:
import {
GraphQLObjectType,
GraphQLInt,
GraphQLString,
GraphQLSchema,
GraphQLList,
GraphQLNonNull
} from 'graphql';
import db from '../models/index.js';
import Auth from '../classes/auth';
after.js可以这样:
const Schema = new GraphQLSchema({
query: Query,
mutation: Mutation
})
export default Schema;
其他文件将包含如下对象:
const Funcionario = new GraphQLObjectType({
name: 'Funcionario',
description: 'This represent a Funcionario',
fields: () => {
return {
id: {
type: GraphQLInt,
resolve(funcionario, args) {
return funcionario.id;
}
},
CPF: {
type: GraphQLString,
resolve(funcionario, args) {
return funcionario.CPF;
}
},
nome: {
type: GraphQLString,
resolve(funcionario, args) {
return funcionario.nome;
}
},
sobrenome: {
type: GraphQLString,
resolve(funcionario, args) {
return funcionario.sobrenome;
}
},
sessions: {
type: new GraphQLList(Session),
resolve(funcionario, args) {
return funcionario.getSessions();
}
}
}
}
})
参见https://github.com/francoisa/todo/tree/master/server/graphql/types
todoType.js有一个viewerType的引用,它在viewerType.js
中定义viewtype .js from todoType
相关文章:
- 如何在未直接触发的情况下停止事件
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 在不使用jquery的情况下查找页面中的所有锚点并附加函数
- 在不打开聊天屏幕的情况下制作Zopim-ding代理
- 在不阻止默认行为的情况下检测IE10中的缩放
- 如何在不传递此信息的情况下查找被调用的元素
- 如何在不刷新页面的情况下更新显示框
- 有没有一种方法可以在控制台关闭的情况下让console.log()在IE中记录消息
- JavaScript-在手机上不工作的情况下,在外部单击时隐藏元素
- 在我的情况下,如何进行http请求
- 在不知道深度或父属性的情况下从对象中删除属性
- 在不破坏未定义函数的情况下,对多个视图使用单个js文件
- ROR:如何在不重新加载浏览器的情况下从控制器获取参数
- 如何在不影响其他元素的情况下扩展DIV
- 如何在内联依赖项并将图像转换为dataURI的情况下完全提取网页
- 在不移动内部文本的情况下缩放元素的效果
- 在不设置协议的情况下,使用javascript/jquery更改iframe-src
- 默认情况下折叠和展开嵌套列表
- 如何在不单击javascript中的按钮的情况下触发事件
- 如何在没有循环依赖的情况下在GraphQL中拆分模式