GraphQL edge/predicate pointing to multiple different types

In GraphQL±, the following is possible:

type Note {
  <~HAS_NOTE>
}

This is useful for acquiring the nodes that point to this Note node through a HAS_NOTE edge.
How can this behaviour be replicated in GraphQL? Is there any way to achieve links to multiple different types in only one predicate?

I think this graphql example might help in achieving what you want. The @hasInverse directive has capability to hold two-way edges.

1 Like

Thanks.
However, is there any way to achieve links to multiple different types in only one predicate?

type Note {
  NOTE_FOR: # generic type here
}

Except Interface, I haven’t seen any other approach.

1 Like

We are going to have Unions soon, please have a look at the RFC for Union types.
That may be what you are looking for.

2 Likes

Hi @gorillastanley
Extending @abhijit-kar suggestion, we can define an interface that will help with the flexibility to achieve links to multiple types via one predicate.
For example:
Consider following schema:

type User {
    userId: ID!
    username: String! @search(by: [hash, term])
    email: String! @search(by: [hash, regexp])
    content: [Content!]
}

interface Content {
    cId: ID!
    name: String! @search(by: [hash, regexp])
}

type Course implements Content {
    chapters: [Chapter!]!
}

type Chapter {
    name: String! @search(by: [hash, regexp])
    data: String! @search(by: [hash, regexp])
}

type Question implements Content {
    questions: String! @search(by: [hash, regexp])
    answer: String! @search(by: [hash, regexp])
}

Then we can have mutations in the following order:

  1. Create Course
mutation {
  addCourse(input: [{
  	name: "Welcome to Dgraph",
    chapters: [
      {
        name: "Introduction to graphql",
        data : "Graphql is Easy"
      }
    ]

  }]) {
    course {
      cId
    }
  }
}

  1. Create Question
mutation {
  addQuestion(input: [{
  	name: "Questions: Welcome to Dgraph",
    questions: "Did you like it?",
    answer: "yes"
  }]) {
    question {
      cId
    }
  }
}
  1. Create User
mutation {
  addUser(input: [{
    username: "XYZ",
    email: "xyz@abc.com",
    content: [
     {
      cId: "0x3" #check this id
    },
      {
        cId: "0x5" #check this id
      }
    ]
    }]) {
    user {
      userId
      username
      Content {
        cId
        name
        ... on Course {
          chapters {
            name
            data
          }
        }

        ... on Question {
          questions
          answer
        }
      }
    }
  }
}

Notice the return of the third mutation. content points to two different types i.e. Course and Question. Using @hasInverse directive you can manage two-way edges.

2 Likes

I’m grateful for your highly detailed response.

To clarify: create an interface, and then I can point to multiple different types by having those different types implement the interface?

Yes

1 Like