2016-08-18 102 views
12

我的问题与Javascript circular dependency in GraphQL code类似,但我的问题不在于结构和数据库级别,而是在JavaScript(ES6)中。如何在没有循环依赖的情况下在GraphQL中拆分模式?

我的模式定义越来越大,但我没有看到我可以将文件分割成几部分。这似乎是合乎逻辑的基础上,不同的对象类型削减,但带来的循环依赖与此同样非常简单,非工作例如:

// -- 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, 
     /*...*/ 
     }), 
    }); 

有一个常见的方式或最佳实践?

+1

有你发现了其他解决方案? –

回答

4

我有同样的问题。我认为更清洁的解决方案是关于使用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(); 
      } 
     } 
    } 
} 
}) 
+1

谢谢,我接受你的解决方案,因为它绝对可以解决我的问题。我仍然试图找到一种不使用grunt的方法,因为这似乎是矫枉过正的,只是因为这个问题才使用它。但是如果没有其他办法,我会执行这一个。 –

+0

如果你想给Apollo的graphql-tools一个镜头,它会真正简化你的代码并使其更具可读性。如果你使用它,我已经写了一个名为schemaglue.js的工具来解决你确切的问题。我已经写了关于扩展和组织您的GraphQL代码:https://hackernoon.com/graphql-schemas-easier-better-structure-31677a640d18希望这有助于。 –

相关问题