2016-08-18 71 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希望這有助於。 –

相關問題