Давайте на минутку предположим, что additionalInformation
был Скаляр, а не Тип объекта:
type Place {
name: String!
additionalInformation: String
}
Значение, возвращаемое распознавателем places
:
[{name: 'Barcelona'}]
Если бы вы сделали аналогичный запрос ...
query {
places {
name
additionalInformation
}
}
Что бы вы ожидали от additionalInformation
? Это значение будет нулевым, поскольку у объекта Place
, возвращенного распознавателем places
, нет свойства additionalInformation
.
Даже если мы сделаем additionalInformation
типом объекта (например, AdditionalInformation
), результат будет тем же - поле additionalInformation
будет иметь нулевое значение. Это потому, что распознаватель по умолчанию (тот, который используется, когда вы не указываете функцию распознавателя для поля) просто ищет свойство с тем же именем, что и поле в родительском объекте. Если ему не удается найти это свойство, возвращается ноль.
Возможно, вы указали преобразователь для поля в AdditionalInformation
(foo
), но этот преобразователь никогда не запускается, потому что в этом нет необходимости - все поле additionalInformation
является нулевым, поэтому все преобразователи для любых полей соответствующего типа пропускаются.
Чтобы понять, почему это желаемое поведение, представьте другую схему:
type Article {
title: String!
content: String!
image: Image
}
type Image {
url: String!
copyright: String!
}
type Query {
articles: [Article!]!
}
У нас есть база данных с таблицей articles
и таблицей images
в качестве слоя данных. Статья может иметь или не иметь изображение, связанное с ней. Мои резольверы могут выглядеть так:
const resolvers = {
Query: {
articles: () => db.getArticlesWithImages()
}
Image: {
copyright: (image) => `©${image.year} ${image.author}`
}
}
Допустим, наш звонок getArticlesWithImages
преобразуется в одну статью без изображения:
[{title: 'Foo', содержание: 'All about foos'}]
Как потребитель API, я прошу:
query {
articles {
title
content
image
}
}
Поле image
является необязательным. Если я возвращаю объект статьи с нулевым полем image
, я понимаю, что в БД не было никакого связанного изображения. Как клиент переднего плана я знаю, что не нужно отображать изображение.
Что произойдет, если GraphQL вернет значение для image
независимо? Очевидно, наш распознаватель сломался бы, так как ему не передавалось бы какое-либо родительское значение. Более того, однако, как потребитель API, мне теперь нужно было бы проанализировать содержимое image
и каким-то образом определить, действительно ли изображение было связано со статьей, и я должен что-то с этим сделать.
TLDR;
Как вы уже предложили, решение здесь состоит в том, чтобы указать преобразователь для additionalInfo
. Вы также можете просто вернуть это значение в своем places
резолвере, т.е.
return [{name: 'Barcelona', additionalInfo: {}}]
В действительности, если форма вашей схемы совпадает с формой вашего нижележащего слоя данных, вряд ли вы столкнетесь с такой проблемой при работе с реальными данными.