Mutations

The most broadly affected area of functionality by the 2.0.0 upgrade are the nested operations of Mutations, to faciliate the mutation of and filtering on relationship properties.

The examples in this section will be based off the following type definitions:

type Actor {
    name: String!
    movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}

type Movie {
    title: String!
    actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}

The theme that you will notice during this section is that as a general rule of thumb, a node field will need adding to your inputs where it will also be possible to filter on relationship properties.

Create

Focussing on the createMovies Mutation, notice that the definition of the createMovies Mutation is unchanged:

input MovieCreateInput {
    title: String!
    actors: MovieActorsFieldInput
}

type Mutation {
    createMovies(input: [MovieCreateInput!]!): CreateMoviesMutationResponse!
}

There are no changes to any of the arguments or types at this level. However, within its nested operations, type modifications have taken place to allow for relationship properties.

In practice, take a Mutation that creates the film "The Dark Knight" and then:

  • Creates a new actor "Heath Ledger"

  • Connects to the existing actor "Christian Bale"

In the previous version of the library, this would have looked like this:

mutation {
    createMovies(
        input: [
            {
                title: "The Dark Knight"
                actors: {
                    create: [
                        {
                            name: "Heath Ledger"
                        }
                    ]
                    connect: [
                        {
                            where: {
                                name: "Christian Bale"
                            }
                        }
                    ]
                }
            }
        ]
    ) {
        movies {
            title
        }
    }
}

This will now have to look like this in order to function in the same way:

mutation {
    createMovies(
        input: [
            {
                title: "The Dark Knight"
                actors: {
                    create: [
                        {
                            node: {
                                name: "Heath Ledger"
                            }
                        }
                    ]
                    connect: [
                        {
                            where: {
                                node: {
                                    name: "Christian Bale"
                                }
                            }
                        }
                    ]
                }
            }
        ]
    ) {
        movies {
            title
        }
    }
}

Note the additional level "node" before specifying the actor name for the create operation and in the connect where. This additional level allows for the setting of relationship properties for the new relationship, and filtering on existing relationship properties when looking for the node to connect to. See the page Mutations for details on this.

Update

Focussing on the updateMovies Mutation, notice that the definition of the updateMovies Mutation is unchanged:

type Mutation {
    updateMovies(
        where: MovieWhere
        update: MovieUpdateInput
        connect: MovieConnectInput
        disconnect: MovieDisconnectInput
        create: MovieRelationInput
        delete: MovieDeleteInput
    ): UpdateMoviesMutationResponse!
}

The create and connect nested operations are primarily the same as in the createMovies Mutation, so please see the Create section for the difference for these operations.

The delete nested operation is primarily the same as in the deleteMovies Mutation, so please see the Delete section for that.

Update

For example, say that you accidentally misspelt Christian Bale’s surname and wanted to fix that. In the previous version, you might have achieved that by:

mutation {
    updateMovies(
        where: {
            title: "The Dark Knight"
        }
        update: {
            actors: [
                {
                    where: {
                        name_ENDS_WITH: "Bail"
                    }
                    update: {
                        name: "Christian Bale"
                    }
                }
            ]
        }
    ) {
        movies {
            title
            actors {
                name
            }
        }
    }
}

This will now have to look like this in order to function in the same way:

mutation {
    updateMovies(
        where: {
            title: "The Dark Knight"
        }
        update: {
            actors: [
                {
                    where: {
                        node: {
                            name_ENDS_WITH: "Bail"
                        }
                    }
                    update: {
                        node: {
                            name: "Christian Bale"
                        }
                    }
                }
            ]
        }
    ) {
        movies {
            title
            actors {
                name
            }
        }
    }
}

Note the added layer of abstraction of node in both the where and update clauses.

Disconnect

For example, say you mistakenly put Ben Affleck as playing the role of Batman in "The Dark Knight", and you wanted to disconnect those nodes. In the previous version, this would have looked like:

mutation {
    updateMovies(
        where: {
            title: "The Dark Knight"
        }
        disconnect: {
            actors: [
                {
                    where: {
                        name: "Ben Affleck"
                    }
                }
            ]
        }
    ) {
        movies {
            title
            actors {
                name
            }
        }
    }
}

This will now have to look like this in order to function in the same way:

mutation {
    updateMovies(
        where: {
            title: "The Dark Knight"
        }
        disconnect: {
            actors: [
                {
                    where: {
                        node: {
                            name: "Ben Affleck"
                        }
                    }
                }
            ]
        }
    ) {
        movies {
            title
            actors {
                name
            }
        }
    }
}

Delete

Focussing on the deleteMovies Mutation, notice that the definition of the deleteMovies Mutation is unchanged:

input MovieDeleteInput {
    actors: [MovieActorsDeleteFieldInput!]
}

type Mutation {
    deleteMovies(where: MovieWhere, delete: MovieDeleteInput): DeleteInfo!
}

There are no changes to any of the arguments or types at this level, but there are some details to note in the MovieActorsDeleteFieldInput type.

Previously, you would have expected this to look like:

input MovieActorsDeleteFieldInput {
    delete: ActorDeleteInput
    where: ActorWhere
}

This allowed you to filter on fields of the Actor type and delete based on that. However, following this upgrade, you will find:

input MovieActorsDeleteFieldInput {
    delete: ActorDeleteInput
    where: MovieActorsConnectionWhere
}

This means that not only can you filter on node properties, but also relationship properties, in order to find and delete Actor nodes.

In practice, a Mutation that deletes the film "The Dark Knight" and the related actor "Christian Bale" would have previously looked like this:

mutation {
    deleteMovies(
        where: {
            title: "The Dark Knight"
        }
        delete: {
            actors: {
                where: {
                    name: "Christian Bale"
                }
            }
        }
    ) {
        nodesDeleted
        relationshipsDeleted
    }
}

This will now have to look like this in order to function in the same way:

mutation {
    deleteMovies(
        where: {
            title: "The Dark Knight"
        }
        delete: {
            actors: {
                where: {
                    node: {
                        name: "Christian Bale"
                    }
                }
            }
        }
    ) {
        nodesDeleted
        relationshipsDeleted
    }
}

Note the additional level "node" before specifying the actor name.