Relations
You can add fields for relations using the t.relation
method:
t.relation
defines a field that can be pre-loaded by a parent resolver. This will create something
like { include: { author: true }}
that will be passed as part of the query
argument of a
prismaField
resolver. If the parent is another relation
field, the includes will become nested,
and the full relation chain will be passed to the prismaField
that started the chain.
For example the query:
the me
prismaField
would receive something like the following as its query parameter:
This will work perfectly for the majority of queries. There are a number of edge cases that make it impossible to resolve everything in a single query. When this happens Pothos will automatically construct an additional query to ensure that everything is still loaded correctly, and split into as few efficient queries as possible. This process is described in more detail below
Fallback queries
There are some cases where data can not be pre-loaded by a prisma field. In these cases, pothos will
issue a findUnique
query for the parent of any fields that were not pre-loaded, and select the
missing relations so those fields can be resolved with the correct data. These queries should be
very efficient, are batched by pothos to combine requirements for multiple fields into one query,
and batched by Prisma to combine multiple queries (in an n+1 situation) to a single sql query.
The following are some edge cases that could cause an additional query to be necessary:
- The parent object was not loaded through a field defined with
t.prismaField
, ort.relation
- The root
prismaField
did not correctly spread thequery
arguments in is prisma call. - The query selects multiple fields that use the same relation with different filters, sorting, or limits
- The query contains multiple aliases for the same relation field with different arguments in a way that results in different query options for the relation.
- A relation field has a query that is incompatible with the default includes of the parent object
All of the above should be relatively uncommon in normal usage, but the plugin ensures that these types of edge cases are automatically handled when they do occur.
Filters, Sorting, and arguments
So far we have been describing very simple queries without any arguments, filtering, or sorting. For
t.prismaField
definitions, you can add arguments to your field like normal, and pass them into
your prisma query as needed. For t.relation
the flow is slightly different because we are not
making a prisma query directly. We do this by adding a query
option to our field options. Query
can either be a query object, or a method that returns a query object based on the field arguments.
The returned query object will be added to the include section of the query
argument that gets
passed into the first argument of the parent t.prismaField
, and can include things like where
,
skip
, take
, and orderBy
. The query
function will be passed the arguments for the field, and
the context for the current request. Because it is used for pre-loading data, and solving n+1
issues, it can not be passed the parent
object because it may not be loaded yet.