Fields that are directly created on the node, meaning fields that are provided through source and transformer plugins (e.g., relativePath
, size
, and accessTime
in nodes of type File
), are typically queried through the GraphQL API in a query similar to the following:
node {
relativePath,
extension,
size,
accessTime
}
These fields are created using the inferObjectStructureFromNodes
function in src/schema/infer-graphql-type.js. Based on what kind of object the function is dealing with as it encounters new objects, it can encompass one of the following three subcategories of fields provided on the created Node
object:
- A field provided through a mapping in gatsby-config.js
- A field having a value provided through a foreign key reference (ending in
___NODE
) - A plain object or value (such as a string) that is passed in
First, for fields provided through mappings in gatsby-config.js, if the object field being sent for GraphQL type generation is configured in a custom manner in the Gatsby configuration file, it requires special handling. For instance, a typical mapping might look like the following, where we’re mapping a linked type, AuthorYaml
, to the MarkdownRemark
type so that we make the AuthorYaml.name
field available in MarkdownRemark
as MarkdownRemark.frontmatter.author
:
// gatsby-config.js
mapping
:
{
"MarkdownRemark.frontmatter.author"
:
`AuthorYaml.name`
,
}
In this situation, the field generation is handled by the inferFromMapping
function in src/schema/infer-graphql-type.js. When invoked, the function finds the type to which the identified field is mapped (AuthorYaml
), which is known as the linkedType
. If a field to link by (linkedField
, in this scenario name
) is not provided to the function, it defaults to id
.
Then, Gatsby declares a new GraphQL field whose type is AuthorYaml
(which is searched for within the existing list of gqlType
s). Thereafter, the GraphQL field resolver will acquire the value for the given node (in this example, the author
string that should be mapped into the identified field) and conduct a search through all the nodes until it finds one with a matching type and matching field value (i.e., the correct AuthorYaml.name
).
Second, for foreign key references, the suffix ___NODE
indicates that the value of the field is an id
that represents another node present in the Redux store. In this scenario, the inferFromFieldName
function in src/schema/infer-graphql-type.js handles the field inference. In this process, which is quite similar to the field mapping process described previously, Gatsby deletes ___NODE
from the field name (converting author___NODE
into author
, for instance). Then it searches for the linkedNode
that the id
represents in the Redux store (the exampleValue
for author
, which is an id
). Upon identifying the correct node through this foreign key, Gatsby acquires the type in the gqlType
s list via the internal.type
value. In addition, Gatsby will accept a linkedField
value that adheres to the format nodeFieldName___NODE___linkedFieldName
(e.g., author___NODE___name
can be provided instead of id
).
Then, Gatsby returns a new GraphQL field sharing the same type as that represented by the foreign key. The GraphQL field resolver sifts through all the available Redux nodes until it encounters one with the same id
. If the foreign key value is instead an array of id
s, then Gatsby will return a GraphQLUnionType
; i.e., a union of all linked types represented in the array.
Third, for plain objects or value fields, the inferGraphQLType
function in src/schema/infer-graphql-types.js is the default handler. In this scenario, Gatsby creates a GraphQL field object whose type it infers directly by using typeof
in JavaScript. For instance, typeof(value) === 'string'
would result in the type GraphQLString
. As the graphql-js
library handles this automatically for Gatsby, there is no need for additional resolvers.
However, if the value provided is an object or an array requiring introspection, Gatsby uses inferObjectStructureFromNodes
to recurse through the structure and create new GraphQL fields. Gatsby also creates custom GraphQL types for File
(src/schema/types/type-file.js) and Date
(src/schema/types/type-date.js): if the value looks like it could be a filename or a date, then Gatsby will return the correct custom type.
NOTE
For more information about how File
types are inferred, consult the Gatsby documentation’s schema inference section on File
types.
Leave a Reply