Interface types

This page describes how to use and define interfaces on relationship fields.

Creating an interface field

The following schema defines an Actor type, that has a relationship ACTED_IN, of type [Production!]!. Production is an interface type with Movie and Series implementations.

interface Production {
    title: String!
    actors: [Actor!]! @declareRelationship
}

type Movie implements Production {
    title: String!
    actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn")
    runtime: Int!
}

type Series implements Production {
    title: String!
    actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn")
    episodes: Int!
}

type ActedIn @relationshipProperties {
    role: String!
}

type Actor {
    name: String!
    actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn")
}

These type definitions will be used for the rest of the examples in this chapter.

Querying an interface

The following will return all productions with title starting "The " for every actor:

query GetProductionsStartingWithThe {
    actors {
        name
        actedIn(where: { node: { title_STARTS_WITH: "The " } }) {
            title
            ... on Movie {
                runtime
            }
            ... on Series {
                episodes
            }
        }
    }
}

The following query will only return the movies with title starting with "The " for each actor by filtering them by typename_IN:

query GetMoviesStartingWithThe {
    actors {
        name
        actedIn(where: { node: { title_STARTS_WITH: "The ", typename_IN: [Movie]  } }) {
            title
            ... on Movie {
                runtime
            }
        }
    }
}

Creating using an interface field

The below mutation creates an actor and some productions they’ve acted in:

mutation CreateActorAndProductions {
    createActors(
        input: [
            {
                name: "Chris Pratt"
                actedIn: {
                    create: [
                        {
                            edge: {
                                role: "Mario"
                            }
                            node: {
                                Movie: {
                                    title: "Super Mario Bros"
                                    runtime: 90
                                }
                            }
                        }
                        {
                            edge: {
                                role: "Starlord"
                            }
                            node: {
                                Movie: {
                                    title: "Guardians of the Galaxy"
                                    runtime: 122
                                }
                            }
                        }
                        {
                            edge: {
                                role: "Andy"
                            }
                            node: {
                                Series: {
                                    title: "Parks and Recreation"
                                    episodes: 126
                                }
                            }
                        }
                    ]
                }
            }
        ]
    ) {
        actors {
            name
            actedIn {
                title
            }
        }
    }
}

Nested interface operations

Operations on interfaces are abstract until you instruct them not to be. Take the following example:

mutation CreateActorAndProductions {
    updateActors(
        where: { name: "Woody Harrelson" }
        connect: {
            actedIn: {
                where: { node: { title: "Zombieland" } }
                connect: { actors: { where: { node: { name: "Emma Stone" } } } }
            }
        }
    ) {
        actors {
            name
            actedIn {
                title
            }
        }
    }
}

The above mutation:

  1. Finds any Actor nodes with the name "Woody Harrelson".

  2. Connects the "Woody Harrelson" node to a Production node with the title "Zombieland".

  3. Connects the connected Production node to any Actor nodes with the name "Emma Stone".

Querying an interface

In order to set which implementations are returned by a query, a filter where needs to be applied. For example, the following query returns all productions (movies and series) with title starting "The " for every actor:

query GetProductionsStartingWithThe {
    actors {
        name
        actedIn(where: { node: { title_STARTS_WITH: "The " } }) {
            title
            ... on Movie {
                runtime
            }
            ... on Series {
                episodes
            }
        }
    }
}