GraphQL one-to-many self-referential relations
This tutorial assumes that you have successfully completed the Dashboard quick start tutorial, and that you still have the Fauna Dashboard open in a browser tab/window. Create a new database before you start the tutorial. If your Dashboard session has expired:
|
To form bi-directional relations in GraphQL requires using the
@relation
directive, which is
explained in the GraphQL
relations.
In this tutorial, we explore how to form one-to-many relations from a
GraphQL Type to itself. We are using a generic Person
Type as an example of
modeling parent/child relations. That is, every Person
document can have one
parent and multiple children relations, where a parent and child are also of
the same Person
Type. The same can be applied to any use case where
one-to-many self-referential relation holds. A common example is an Employee
and Manager
relation. An Employee
can report to one Manager
(parent relation), where each Manager
is also an Employee
and can have
relation with multiple other Employees
as reports (child relation).
To create such self-referential relations, the relations in GraphQL are modeled using an intermediate "link table" Type.
Tutorial
Let’s first define a simple Person
Type, and attempt to make a relation to
itself.
-
Create a new schema file
Create the file
schema-self_ref.graphql
with the following content: -
Import the GraphQL schema
-
Click the IMPORT SCHEMA button. If you do not see the button, click the REPLACE SCHEMA button.
-
In the file dialog, locate and select the file
schema-self_ref.graphql
, then click the file dialog’s Open button.
An error message appears:
Many to many self-references are not allowed
The problem is that the GraphQL API does not support applying the dynamically-generated document ID to a document field as a single step, which is required to make a self-referential relation.
To solve this problem, the schema needs to be adjusted to introduce a Type dedicated to managing the relation.
-
-
Modify the schema to create a
PersonLink
Type to establish a self-referencing one-to-many relationCreate the file
schema-self_ref.graphql
with the following content: -
-
Click the REPLACE SCHEMA button.
-
In the file dialog, locate and select the file
schema-self_ref.graphql
, then click the file dialog’s Open button.
This time, the schema import should be successful.
When the schema is imported, the Fauna GraphQL API creates collections named
Person
andPersonLink
. It specifies that aPerson
document has exactly one parent document. This means that there can only ever be one relation to aPerson
as a child. The schema also specifies than aPerson
can have a list of children, so that onePerson
document can be related to many childPerson
documents. -
-
Create a
Person
and its parent-child relationsNow that you have the new schema in place, to create relations between the parent/child persons, you have to create the "links".
-
Copy the following GraphQL mutation, which creates a
Person
document namedPerson1
, plus its children documentsChild1
andChild2
: -
Click the "new tab"
+
button in the GraphQL Playground screen in your browser (at the top left, just right of the last query tab). -
Paste the query into the left panel, and click the "Play" button.
The query should execute and it should create a list of
PersonLink
documents, each one creating aPerson
as a child and aPerson
as a parent. The response should appear in the panel on the right:{ "data": { "createPerson": { "_id": "335202398647616000", "name": "Person1", "children": { "data": [ { "_id": "335202398657054208", "child": { "_id": "335202398657053184", "name": "child1" } }, { "_id": "335202398658102784", "child": { "_id": "335202398658101760", "name": "child2" } } ] } } } }
Alternately, you can create
Person
documents and then create a link to connect parent and child as shown in the Many-to-many self-referential relations tutorial. -
-
Query all children relations of a person
Now that the parent/child relations are in place, let’s verify that for a person.
-
Copy the following GraphQL query:
-
Click the "new tab"
+
button in the GraphQL Playground screen in your browser (at the top left, just right of the last query tab). -
Paste the query into the left panel
-
Replace the string
<$PERSON_ID>
with the value of the_id
field, immediately following thecreatePerson
field, from the previous step’s response. -
Click the "Play" button.
The response, in the right-hand panel, should be similar to:
{ "data": { "findPersonByID": { "name": "Person1", "children": { "data": [ { "child": { "name": "child1" } }, { "child": { "name": "child2" } } ] } } } }
-
Conclusion
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!