Hi @Florian. Let’s see if we can cool off the spicy!
I will ultimately advise that you not use the taskByUser query, because there is an easier, more GraphQL-canonical way to do it. But I’ll try to address your question directly first.
Input types
Correct! The only types that can be used as input arguments are Scalars (e.g. String
, Int
, etc.) Input types are defined with the input
keyword, rather than type
. for example:
input LoginInput {
username: String!,
password: String!
}
So you cannot specify User
as an input. But you can specify an ID
type (which is basically just an alias for String | Int
)
This not not Fauna specific. It’s part of GraphQL. Check out the docs for input types and ID
on graphql.org/learn/schema
Using ID
You can try the following instead:
tasksByUser(user: ID): [Task!]
But you will get another error.
Type mismatch: field 'user' defined at object 'Task' has type 'User'.
See, the schema we provided is just a short-hand for:
tasksByUser(user: ID): [Task!] @index(name: "tasks_by_user")
and it’s trying to create a new index on the fly. Fauna knows that there is a user
field and that it’s an object type.
Note that there is already an index created for you based on the @relation
directive you provided, and it’s name is probably something like task_user_by_user
. It’s used by Fauna to help expand query selections. You cannot use this directly in GraphQL because it’s indexed on the raw user type, which is a Ref, for example Ref(Collection("task"), "123456789")
.
If you want to query an index by an ID directly, then you need to specify the index ahead of time, and include it in the schema. Assuming you have Task and User Collections existing in your DB, you can create the Index in the dashboard
or run this in the shell:
CreateIndex({
name: "tasks_by_user",
unique: false,
serialized: true,
source: "Task",
terms: [
{
field: ["data", "user", "id"]
}
]
})
then you can intentionally reference it in your schema when you upload:
type Query {
# ...
tasksByUser(user: ID): [Task!] @index(name: "tasks_by_user")
# ..
}
How to do this the GraphQL way without any extra work
My advise to not create any top level query for “object_by_object” unless you are trying to wrap additional logic around it. In that case, you’re looking at using @resolver
to work with Functions.
GraphQL lets you query data as if it is… a graph!! So let’s “traverse” the graph to find all tasks that belong to a given user.
query TasksByUser {
# findUserById is automatically generated for you
findUserById(id: "123456789") {
_id
tasks {
_id
title
completed
}
}
}
Cool thing is that this is already ready for pagination!
query TasksByUser {
findUserById(id: "123456789") {
_id
# can paginate user tasks
tasks (_size: 10) {
_id
title
completed
}
}
}