linkingObjects for GraphQL?

I used linkingObjects for the inverse relationship as described here.

But un-intuitively, it seems relationship was not created accordingly for the JSON schema. So I was not able to query the related objects with GraphQL.

What would be the recommended way to use inverse relationship with GraphQL?

@Toshi I’m not sure how you went about creating the inverse relationship but it looks like you tried to create it locally in your RN application based on the link you provided.

You should be able to confirm the inverse relationship was created in the “Relationships” tab on the “Rules” page to ensure it’s also available for your GraphQL Schema.

Since I can’t see what your app looks like, you can also message me the link to your application so I can take a look.

1 Like

Hi Sumedha, thanks! Please let me share the code then.

So let’s say a Thread has many Chats, and a Chat belongs to one Thread.
I defined a schema based on TypeScript Class, by reading this page.

class Chat {
  public _id: ObjectId;
  public content: string;
  public thread: Thread;

  public static schema: Realm.ObjectSchema = {
    name: "Chat",
    primaryKey: "_id",
    properties: {
      _id: "objectId",
      content: "string",
      thread: "Thread",
    },
  };
}

class Thread {
  public _id: ObjectId;
  public title: string;
  public chats: Realm.List<Chat>;

  public static schema: Realm.ObjectSchema = {
    name: "Thread",
    primaryKey: "_id",
    properties: {
      _id: "objectId",
      title: "string",
      chats: {
        type: 'linkingObjects',
        objectType: 'Chat',
        property: 'thread'
      }
    },
  };
}

I enabled Sync, and executed realm.write.

realm.write(() => {
  const thread = realm.create("Thread", {
    _id: new ObjectId(),
    title: "Parent thread",
  });

  const chat = realm.create("Chat", {
    _id: new ObjectId(),
    content: "Child chat",
    thread: thread,
  });
});

Then the chat->thread relationship was successfully generated like a charm!
image

And So I was able to query GraphQL perfectly as expected.

query{
  chats{
    content
    thread{
      title
    }
  }
}

This responds successfully like:

{
  "data": {
    "chats": [
      {
        "content": "Child chat",
        "thread": {
          "title": "Parent thread"
        }
      }
    ]
  }
}

(*I split my reply into two, due to 1-photo-per-post restriction)

However, the problem is thread->chats part.

Using JavaScript (TypeScript), I was able to retrieve thread.chats intuitively:

const threads = realm.objects("Thread");
threads.map((thread) => {
  thread.chats.map((chat) =>{
    console.log(chat.content);
  });
})

On the other hand, using GraphQL, I didn’t find relationship definition and thus can’t query relationship:
image

What I want to query is like this:

query{
  threads{
    title
    chats{
      content
    }
  }
}

But it gets

"message": "Cannot query field \"chats\" on type \"Thread\".",

What do you think?

Hi Toshi –

So, the inverse relationships definitions in Realm are local to the database and do not get pushed to cloud, even though one-way relationships do.

To work around this, you can use a Computed Property Custom Resolver to mimic the same functionality where the thread computes the chat that it belongs to and returns the chat object.

Hi Sumedha, thank you. I think I succeeded to implement a custom resolver to achieve the inverse relationship. JFYI the code was like:

exports = async (thread) => {
  const cluster = context.services.get("mongodb-atlas");
  const chats = cluster.db("main").collection("chats").find({
    thread: thread._id
  }).toArray();
  return chats;
};

Custom Resolver looks really nice and versatile. It is also great as it’s explicit to show what kind of queries will actually run behind. I thought if there is a guide about this topic in the Custom Resolver page or somewhere else in Realm GraphQL docs, that would be even better.

I guess at some point I will need to implement another resolver like mutations, but for now, it’s great and I can proceed. Thank you!

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