Тип объединения graphqlj-js, аргументы доступа

Я пытаюсь понять, как получить доступ к полю argsretrieveRowsWithoutLocations. Однако я даже не уверен, что входит в параметр value в функции resolveType UnionType.

Я просматриваю документацию https://graphql.org/graphql-js/type/#graphqluniontype, но она довольно краткая и не содержит подробностей о том, откуда взята эта информация. Я пробовал искать другие источники, но они не являются graphql-js.

Я пытаюсь получить доступ к args.type и проверить его значение, что затем позволяет объединению решить, какой тип он должен возвращать.

let rows_union =
    new graphql.GraphQLUnionType({
        name: 
            "rows_union",
        types: 
        [
            many_item,
            many_list,
            many_display_list, 
        ],
        resolveType(value) 
        {
            switch(value)
            {
                case "item":
                    return many_item
                case "list":
                    return many_list
                case "display_list":
                    return many_display_list
            }
        }
    })

// Define the Query type
var query =
    new graphql.GraphQLObjectType({
        name: "Query",
        fields:
        {
            retrieveRowsWithoutLocations:
            {
                type:
                    rows_union,
                args:
                {
                    _id:
                    {
                        type:
                            nonNullId()
                    },
                    page:
                    {
                        type:
                            nonNullInt()
                    },
                    page_length:
                    {
                        type:
                            nonNullInt()
                    },
                    type:
                    {
                        type:
                            nonNullString()
                    },
                },
                async resolve ()
                {

                }
            },
        }
    })


let many_type =
    new graphql.GraphQLObjectType({
        name: "many_"+name,
        fields: {
            results: {
                type: graphql.GraphQLList(type)
            },
            total: {
                type: graphql.GraphQLNonNull(graphql.GraphQLInt)
            },
        }
    })

type — еще один ObjectType

Можете ли вы включить код для many_item,` many_list, and many_display_list`?

Daniel Rearden 25.04.2019 11:35

@DanielRearden нет необходимости ... это просто типы объектов. Вы можете легко представить, что они Int, String или Float, и это не имеет значения...

A. L 25.04.2019 11:41

Я не могу этого сделать, потому что скаляры нельзя использовать внутри объединения: P Я хотел посмотреть на этот код, чтобы удовлетворить мой ответ для вашего конкретного варианта использования.

Daniel Rearden 25.04.2019 11:50

@DanielRearden Я добавил это, но не думаю, что в этом есть какой-то смысл, поскольку я спрашиваю о доступе к args в запросе/мутации, что, похоже, не работает, поскольку функция resolveType фактически считывает результат. Вместо этого я собираюсь разделить его на несколько запросов.

A. L 25.04.2019 12:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
290
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы не можете получить прямой доступ к каким-либо параметрам преобразователя внутри resolveType (или isTypeOf). Когда поле разрешается, преобразователь возвращает некоторое значение или обещание, которое будет разрешаться в это значение. В случае поля, которое возвращает тип вывода, интерфейс или объединение, это значение должно быть объектом JavaScript. Именно это значение затем передается в resolveType, которое используется для определения того, какой тип фактически возвращается в ответе во время выполнения.

Учитывая схему, как

union Animal = Bird | Fish

type Bird {
  numberOfWings: Int
}

type Fish {
  numberOfFins: Int
}

type Query {
  animal: Animal
}

вы можете представить, что преобразователь для поля animal возвращает объекты JavaScript, такие как { numberOfWings: 2 }{ numberOfFins: 4 }. Здесь мы могли бы использовать простую эвристику для определения типа:

resolveType: (value) => {
  if (value.numberOfWings !== undefined) {
    return 'Bird'
  } else if (value.numberOfFins !== undefined) {
    return 'Fish'
  }
  throw new TypeError(`Unable to resolve type for Animal with value: ${value}`)
}

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

resolveType: (value) => {
  if (value instanceof BirdModel) {
    return 'Bird'
  } else if (value instanceof FishModel) {
    return 'Fish'
  }
  throw new TypeError(`Unable to resolve type for Animal with value: ${value}`)
}

Как бы ни выглядела наша условная логика, просто помните, что мы всегда просто проверяем значение, возвращаемое преобразователем, каким бы оно ни было.

Все становится немного сложнее, если вы не используете классы, а два или более типов имеют одинаковую структуру. Или, как в вашем случае, когда отличительное свойство (results) является массивом, поскольку проверка одного из элементов невозможна. Представьте, что наш союз вместо этого выглядит так:

union Animal = Cat | Dog

type Cat {
  numberOfPaws: Int
}

type Dog {
  numberOfPaws: Int
}

Здесь, к сожалению, мы должны полагаться на наш преобразователь, чтобы предоставить дополнительную информацию. Например, мы могли бы вернуть произвольное поле для определения типа:

// Resolver for animal field
resolve: () => {
  return {
    numberOfPaws: 4,
    kind: 'Dog',
  }
}

// Union
resolveType: (value) => {
  return value.kind
}

Но на самом деле мы можем сделать лучше, полагаясь на реализации resolveType и isTypeOf по умолчанию:

resolve: () => {
  return {
    numberOfPaws: 4,
    __typename: 'Dog',
  }
}

Явным образом возвращая __typename таким образом, мы фактически можем получить вообще не определять resolveType. Однако имейте в виду, что, опять же, это создает зависимость от преобразователя. Там, где это возможно, вам, вероятно, следует использовать resolveType с проверками instanceof, чтобы отделить resolveType от вашей логики преобразователя.

Другие вопросы по теме