Динамическое создание схемы graphql с циклическими ссылками


Используя graphql-js, мне нужно создать схему graphql динамически, повторяя массив некоторых данных, например:

[{
    name: 'author',
    fields: [{
        field: 'name'
    }, {
        field: 'books',
        reference: 'book'
    }]
}, {
    name: 'book',
    fields: [{
        field: 'title'
    }, {
        field: 'author',
        reference: 'author'
    }]
}]

Проблема заключается в круговых ссылках. Когда я создаю AuthorType, мне нужно, чтобы BookType уже был создан, и наоборот.

Таким образом, полученная схема должна выглядеть следующим образом:

type Author : Object {  
  id: ID!
  name: String,
  books: [Book]
}

type Book : Object {  
  id: ID!
  title: String
  author: Author
}

Как я могу это решить?

2 2

2 ответа:

Цитируется из официальной документации

Http://graphql.org/docs/api-reference-type-system/

Когда два типа должны ссылаться друг на друга, или тип должен ссылаться для себя в поле можно использовать выражение функции (оно же замыкание или стук), чтобы лениво снабжать поля.

var AddressType = new GraphQLObjectType({
  name: 'Address',
  fields: {
    street: { type: GraphQLString },
    number: { type: GraphQLInt },
    formatted: {
      type: GraphQLString,
      resolve(obj) {
        return obj.number + ' ' + obj.street
      }
    }
  }
});

var PersonType = new GraphQLObjectType({
  name: 'Person',
  fields: () => ({
    name: { type: GraphQLString },
    bestFriend: { type: PersonType },
  })
});

Также посмотрите на этот связанный Ответ круговых типов категорий-подкатегорий

Я решил эту проблему, используя thunk для поля fields.

const User = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: { type: GraphQLID }
  })
});

Когда вы делаете ваши поля thunk, а не литералом объекта, вы можете использовать типы, определенные позже в файле.

Пожалуйста, смотрите этот пост для получения дополнительной информации Есть ли способ избежать циклических зависимостей типа в GraqhQL?

Основываясь на этом посте, я думаю, что это правильный способ сделать это.