Я столкнулся с проблемой, когда мне нужно сослаться на разрешенное поле на родительском элементе внутри __resolveType. К сожалению, поле, на которое мне нужно сослаться, пришло не как часть исходного ответа API для родителя, а из другого распознавателя поля, который я бы не имел значения, но на самом деле это так, поэтому он не определен.
Но мне нужны эти поля (в этом примере; obj.barCount
и obj.bazCount
), чтобы можно было выполнить следующий запрос, поэтому я зашел в тупик. Мне нужно, чтобы они были доступны в функции resolType, чтобы я мог использовать их, чтобы определить, какой тип разрешить в случае определения этого поля.
Вот пример:
Запрос graphql I wi sh, чтобы иметь возможность:
{
somethings {
hello
... on HasBarCount {
barCount
}
... on HasBazCount {
bazCount
}
}
}
Схема:
type ExampleWithBarCount implements Something & HasBarCount & Node {
hello: String!
barCount: Int
}
type ExampleWithBazCount implements Something & HasBazCount & Node {
hello: String!
bazCount: Int
}
interface Something {
hello: String!
}
interface HasBarCount {
barCount: Int
}
interface HasBazCount {
bazCount: Int
}
Решатели:
ExampleWithBarCount: {
barCount: (obj) => {
return myApi.getBars(obj.id).length || 0
}
}
ExampleWithBazCount {
bazCount: (obj) => {
return myApi.getBazs(obj.id).length || 0
}
}
Задача:
Something: {
__resolveType(obj) {
console.log(obj.barCount) // Problem: this is always undefined
console.log(obj.bazCount) // Problem: this is always undefined
if (obj.barCount) {
return 'ExampleWithBarCount';
}
if (obj.bazCount) {
return 'ExampleWithBazCount';
}
return null;
}
}
Любые идеи альтернативных решений или что я упускаю?
Вот еще немного о сценарии использования.
В базе данных у нас есть таблица «сущность». Эта таблица очень проста и только действительно важными столбцами являются id, parent_id, name. type, а затем, конечно, вы можете прикрепить к нему некоторые дополнительные метаданные.
Как и в случае с «entity», типы создаются динамически из внутренней системы управления, и после этого вы можете назначить тип вашей конкретной сущности.
Основная цель «сущности» - установить sh иерархию / дерево вложенных сущностей по parent_id и с разными «типами» (в столбце типа сущности). Будут разные метаданные, но давайте не будем заострять на этом внимание.
Примечание: сущность может быть названа как угодно, а тип может быть любым.
В API у нас будет конечная точка где мы можем получить все сущности с указанным c типом (sidenote: и в дополнение к единственному типу на праве, у нас также есть конечная точка для получения всех сущностей по их таксономии / термину).
В В первой реализации я смоделировал схему, добавив все «известные» типы, которые были в моей спецификации, из UX'er во время разработки. Дерево сущностей может иметь вид, например:
- Компания (или Организация, ..., Корпорация ... и т. Д. 1079 *)
- Филиал (или Регион, ... , et c)
- Фабрика (или Здание, объект, ..., et c)
- Зона (или Комната, ..., et c)
Но эта иерархия - только один из способов, которым это можно сделать. Имена каждого из них могут быть совершенно разными, и вы можете переместить некоторые из них на уровень вверх или вниз или не иметь их вообще, в зависимости от варианта использования.
Единственное, что установлено в камне, это то, что они совместно использовать одну и ту же таблицу базы данных, будут определены столбец / поле типа, и они могут иметь или не иметь дочерние элементы. Нижний слой в иерархии не будет иметь дочерних элементов, а будет иметь машины. Остальные только разные метаданные, которые, я думаю, мы должны игнорировать, чтобы не усложнять это.
Как видите, иерархия должна быть очень гибкой и динамичной c, поэтому я понял, что это не так отличное решение, которое я начал.
На самом нижнем уровне «Зона» в этом случае должно быть поле «машины», которое должно возвращать список машин (они находятся в «машинах»). "таблица в БД, и не часть иерархии, а просто связанная с" entity_id "в таблице" machines ".
У меня были типы схем и преобразователи для всех в приведенной выше иерархии: Организация, Филиал , Factory, Zone et c, но я по большей части просто повторялся, поэтому я подумал, что могу обратиться к интерфейсам, чтобы попытаться обобщить это подробнее.
Поэтому вместо того, чтобы делать
{
companies{
name
branchCount
buildingCount
zoneCount
branches {
name
buildingCount
zoneCount
buildings {
name
zoneCount
zones {
name
machines {
name
}
}
}
}
}
}
И, добавив схему / преобразователи для всех имен имен сущностей, я подумал, что это будет работать:
{
entities(type: "companies") {
name
... on HasEntityCount {
branchCount: entityCount(type: "branch")
buildingCount: entityCount(type: "building")
zoneCount: entityCount(type: "zone")
}
... on HasSubEntities {
entities(type: "branch") {
name
... on HasEntityCount {
buildingCount: entityCount(type: "building")
zoneCount: entityCount(type: "zone")
}
... on HasMachineCount {
machineCount
}
... on HasSubEntities {
entities(type: "building") {
name
... on HasEntityCount {
zoneCount: entityCount(type: "zone")
}
... on HasMachineCount {
machineCount
}
... on HasSubEntities {
entities(type: "zone") {
name
... on HasMachines {
machines
}
}
}
}
}
}
}
}
}
С интерфейсами:
interface HasMachineCount {
machineCount: Int
}
interface HasEntityCount {
entitiyCount(type: String): Int
}
interface HasSubEntities {
entities(
type: String
): [Entity!]
}
interface HasMachines {
machines: [Machine!]
}
interface Entity {
id: ID!
name: String!
type: String!
}
ниже работы ks, но я действительно хочу избежать одного типа с большим количеством необязательных / пустых полей:
type Entity {
id: ID!
name: String!
type: String!
# Below is what I want to avoid, by using interfaces
# Imagine how this would grow
entityCount
machineCount
entities
machines
}
В моей собственной логике c Мне все равно, как называются сущности, только какие поля ожидаются. Я бы хотел избежать одного типа Entity с множеством полей, допускающих обнуляемость, поэтому я подумал, что интерфейсы или объединения будут полезны для разделения вещей, поэтому я в итоге получил HasSubEntities, HasEntityCount, HasMachineCount и HasMachines, поскольку нижний объект не будет иметь сущности ниже, и только нижняя сущность будет иметь машины. Но в реальном коде их было бы намного больше, чем 2, и он мог бы закончиться множеством необязательных полей, если, я думаю, не использовать интерфейсы или объединения каким-либо образом.