hasInverse and how its different from using @reverse on predicates

Users of GraphQL± would know that we have @reverse index that allows you to automatically create reverse edges.

In GraphQL, we have @hasInverse.

type Author {
    posts: [Post] @hasInverse(field: author)
type Post {
    author: Author

So adding a post for an author also adds the author for the post and vice versa.

Under the hood, this is not implemented using @reverse index. There are two separate predicates created here, i.e.

  • Author.posts: [uid]
  • Post.author: uid.

This is because if we were using @reverse instead of creating two different predicates:

  • There is no way to mutate along the reverse edge direction in GraphQL±. So in the example above, you can add both a post for an author and the author for a post. In GraphQL±, you could only do one of those operations.
  • The reverse edge in GraphQL± has to always be of type [uid] which is again limiting. We don’t have that restriction in GraphQL.

Like for @reverse while using @hasInverse we do the deletion in the inverse direction when a deletion in the forward direction happens to make sure there are no dangling edges. So when you delete a post for an author, we also delete the author from the post.