Schema Root Fields and Utility Types
Schema Root Fields are the “entry point” of any GraphQL query. Gatsby generates two root fields for each
Node type that gets created as a result of Schema Generation. Third-party schemas and the
createResolvers API can add additional root fields on top of those.
The root fields that Gatsby generates are used to retrieve either one item of a certain type or many items of that type. For example, for type
BlogPost, Gatsby will create
allBlogPost root fields.
While those fields can be used without any arguments, the additional power lies in the fact that they accept additional parameters to filter, sort or paginate the resulting data. As those parameters depend on a particular type that they are used for, Gatsby generates Utility Types to support those. Those types are used in the root fields to support filtering or sorting, as well as to return Paginated Data.
Plural fields accept four arguments -
filter allows filtering based on node field values (see Filter Types below),
sort sorts the result (see Sorting types below).
limit offsets the result by
skip nodes and limits it to
limit items. Plural root fields return a Connection type (see Pagination Types below) for the returning type (for example,
Singular root fields accept the same
filter parameter as plural, but the
filter is spread directly into arguments. Thus filter parameters need to be passed to the field directly. They return the resulting object directly.
If no parameters are passed, they return a random node of that type (if any exist). That random node type is explicitly undefined and there is no guarantee that it will be stable (or unstable) between builds or rebuilds. If no node was found according to the filter, null is returned.
Gatsby uses a common pattern in GraphQL called Connections. This pattern has nothing to do with connecting anything, but rather is an abstraction over pagination. When you query a connection, you get a slice of the resulting data based on passed
limit parameters. It also allows doing additional operations on a list, like doing grouping or distinct operations.
edges- edge is the actual Node object together with additional metadata regarding it’s location in the page.
node- the actual object, and
prevobjects to get next or previous object from the current one.
nodes- a flat list of Node objects
pageInfo- additional pagination metadata
pageInfo.totalCount- (also available as
totalCountnumber of all nodes that match the filter, before pagination
pageInfo.currentPage- index of the current page (based on 1)
pageInfo.hasPreviousPage- whether there is a next or previous page based on current pagination
pageInfo.itemCount- number of items on current page
perPage- requested number of items on each page
pageCount- total number of pages
distinct(field)- print distinct values for given field
group(field)- return values grouped by a field
For every Node type, a filter GraphQL input type is created. Gatsby has pre-created “operator types” for each scalar, like
StringQueryOperatorType, that has keys as possible operators (for example,
ne) and values as appropriate values for them. Then Gatsby looks at every field in the type and executes roughly the following algorithm.
- If field is a scalar 1.1 Get a corresponding operator type for that scalar type 1.2 Replace field with that type
- If field is not a scalar - recursively go through the nested type’s fields and then assign resulting input object type to the field.
Abridged resulting types:
For sort, GraphQL creates an enum of all fields (including up to 3 levels of nesting) for a particular type.
This field is combined with enum that contains ordering (
DESC) into a sort input type.