将GraphQL类型模块化为单独的文件

将GraphQL类型模块化为单独的文件,graphql,Graphql,我有一个GraphQL实现,其中有一个单一的types/index.js文件,当前包含两个类型定义: const graphql = require('graphql'); const Book = require('../../../models/book'); const Author = require('../../../models/author'); const { GraphQLObjectType, GraphQLString, GraphQLSchema, G

我有一个GraphQL实现,其中有一个单一的types/index.js文件,当前包含两个类型定义:

const graphql = require('graphql');
const Book = require('../../../models/book');
const Author = require('../../../models/author');

const {
  GraphQLObjectType,
  GraphQLString,
  GraphQLSchema,
  GraphQLID,
  GraphQLInt,
  GraphQLList,
  GraphQLNonNull,
} = graphql;

const BookType = new GraphQLObjectType({
  name: 'Book',
  fields: () => ({
    id: { type: GraphQLID },
    name: { type: GraphQLString },
    genre: { type: GraphQLString },
    author: {
      type: AuthorType,
      resolve: (parent, args) => {
        // code to get data from db
        return Author.findById(parent.authorId);
      },
    },
  }),
});

const AuthorType = new GraphQLObjectType({
  name: 'Author',
  fields: () => ({
    id: { type: GraphQLID },
    name: { type: GraphQLString },
    age: { type: GraphQLInt },
    books: {
      type: new GraphQLList(BookType),
      resolve: (parent, args) => {
        // code to get data from db
        return Book.find({authorId: parent.id});
      },
    },
  }),
});

module.exports = {BookType, AuthorType};
这是我导入到schema.js文件中的文件,根查询和转换使用该文件:

const {
  GraphQLObjectType,
  GraphQLString,
  GraphQLSchema,
  GraphQLID,
  GraphQLInt,
  GraphQLList,
  GraphQLNonNull,
} = require('graphql');
const Book = require('../../../models/book');
const Author = require('../../../models/author');
const {BookType, AuthorType} = require('../types');

// QUERIES
//------------------------------------------------------------------------------------------------------
const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    book: {
      type: BookType,
      args: { id: { type: GraphQLID } },
      resolve: (parent, args) => {
        // code to get data from db
        return Book.findById(args.id);
      },
    },
    author: {
      type: AuthorType,
      args: { id: { type: GraphQLID } },
      resolve: (parent, args) => {
        // code to get data from db
        return Author.findById(args.id);
      },
    },
    books: {
      type: new GraphQLList(BookType),
      resolve: (parent, args) => {
        // code to get data from db
        return Book.find({});
      },
    },
    authors: {
      type: new GraphQLList(AuthorType),
      resolve: (parent, args) => {
        // code to get data from db
        return Author.find({});
      }
    },
  },
});

// MUTATIONS
//------------------------------------------------------------------------------------------------------
const Mutation = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    addAuthor: {
      type: AuthorType,
      args: {
        name: { type: new GraphQLNonNull(GraphQLString) },
        age: { type: new GraphQLNonNull(GraphQLInt) }
      },
      resolve(parent, args) {
        let author = new Author({
          name: args.name,
          age: args.age
        });
        return author.save();
      }
    },
    addBook: {
      type: BookType,
      args: {
        name: { type: new GraphQLNonNull(GraphQLString) },
        genre: { type: new GraphQLNonNull(GraphQLString) },
        authorId: { type: new GraphQLNonNull(GraphQLID) },
      },
      resolve(parent, args) {
        let book = new Book({
          name: args.name,
          genre: args.genre,
          authorId: args.authorId,
        });
        return book.save();
      },
    },
  }
});

module.exports = new GraphQLSchema({
  query: RootQuery,
  mutation: Mutation,
});

但随着项目的发展,我预计会有几十种类型的双向关系。因此,我想将所有类型模块化为单独的文件,例如类型/BookType.js类型/AuthorType.js,而不是像我现在这样的单个类型/index.js。考虑到双向关系,实现这一点的最佳方法是什么?

将类型分离到单独的文件中时,需要处理双向关系。在这种情况下,AuthorType需要BookType,反之亦然。因此,您需要在types/BookTypes.js中导入AuthorType,在types/AuthorType.js中导入BookType,但这将引入一个典型的循环依赖性问题(在AuthorType导出之前,它需要BookType,反之亦然),这在节点项目中很常见。你可以阅读更多关于它的内容。若要处理此问题,请在两种类型的文件末尾移动require调用。因此,您的代码看起来有点像这样:

类型/BookType.js

const graphql=require('graphql');
const Book=require('../../../models/Book');
const Author=require('../../../models/Author');
常数{
GraphQLObjectType,
图形字符串,
图形模式,
GraphQLID,
GraphQLInt,
图表列表,
GraphQLNonNull,
}=图形ql;
const BookType=新的GraphQLObjectType({
名称:'书',
字段:()=>({
id:{type:GraphQLID},
名称:{type:GraphQLString},
类型:{type:GraphQLString},
作者:{
类型:AuthorType,
解析:(父级,参数)=>{
//从数据库获取数据的代码
返回Author.findById(parent.authord);
},
},
}),
});
module.exports=书籍类型;
//这是为了防止循环依赖问题,这将导致无限循环的形成
const AuthorType=require(“./AuthorType”)