GraphQL Schema type error when referencing existing index

My schema (truncated):

type User {
  ...
}

type Passage {
  ...
  User:User
}

User does not know anything about Passages. When a new Passage is created, it is connected it to a user using { connect: [user id] }.

I want to retrieve all passages owned by a User given their ID.

I created the following index:
image
The index works as intended when used through the dashboard.

Finally I added the following to my schema:
passageByUser(User:ID):[Passage] @index(name: "passage_by_user")

I am getting a type mismatch error:
Type mismatch: field ā€˜Userā€™ defined at object ā€˜Passageā€™ has type ā€˜Userā€™.

This would make sense if FaunaDb needed to create the index, but because it exists already I would expect this to be working. What is the proper way to do this?

What I did above was based off the solution to this topic, although not the final proposed solution it allowed me to avoid embedding Passages directly in the User documents, which would be ideal.

The error happens because of how the @index works. It expectats that argument names and types match exactly with the fields of the output type. You set your User argument to an ID type, but the Passage user type has field User: User.

If you want to provide this custom functionality, you will need to use the @resolver directive, instead of @index.

That said, I strongly recommend you consider using built in relations before going the custom route.

A more idiomatic approach

You can do this out of the box with GraphQL. You will need to provide a field on the User for connected Passages. I know you said that a User does not know anything about Passages, but you are in fact querying in that way.

Here is a similar question for querying all Todos for a given user.

Rather than provide the related ID, the more idiomatic GraphQL approach is to to query the User, then expand the related fields.

The reason that this way is preferred is that the query results represent your actual ā€œgraphā€ of data. If you create a custom resolver to take an User ID and skip over the user in the results, then you lose your ability to reason about the graph fully. One practical consequence is that you might break your local cache, like what Apollo Client uses, but if you return the whole graph then your cache stays up to date without additional work to link everything together.

type User {
  ...
  passages: [Passage]! @relation
}

type Passage {
  ...
  user:User @relation
}

Then you can immediately query for all Passages for a given User

{
  findUserById(id: "1234") { # <- auto-generated query
    _id
    # other User fields
    passages: {
      after     # pagination is build in!
      data {
        _id
        # other Passage fields
      }
    }
  }
}

what happens if say, 1 user has 10 million passages? and I want only a subset of them without having to do a for loop on 10M entities? how would that query look like?

Thanks!

Iā€™m not sure I understand what you mean by ā€œa subsetā€. Do you mean that you would like to apply an additional filter on the passages, or simply acquire chunks of them at a time?

Pagination is built in to the default generated schema. The default size for Pagination is 64 ā€“ thatā€™s how Fauna works in general. So we can update my example query like the following without changing the schema

{
  findUserById(id: "1234") { # <- auto-generated query
    _id
    # other User fields...
    # apply size limit for paginating Passages
    passages(_size: 100) {
      after     # pagination is build in!
      data {
        _id
        # other Passage fields
      }
    }
  }
}

If you want to apply additional filters for your sub-selections, we donā€™t yet support filters or resolvers on user-type fields yet. That means you would need to create a top level custom resolver to handle the specific logic you desire. If thatā€™s what you need, then I suggest taking another look around the forums and starting a new topic to focus on putting all of those elements together.

EDIT: Actually, it looks like thatā€™s what this one is for :sweat_smile: Help with nested graphql query

haha yeah, my question was solved thank you @ptpaterson !

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.