Skip to content
This repository has been archived by the owner on Sep 3, 2021. It is now read-only.

Feature request: Nested mutations #532

Open
michaeldgraham opened this issue Nov 1, 2020 · 1 comment
Open

Feature request: Nested mutations #532

michaeldgraham opened this issue Nov 1, 2020 · 1 comment

Comments

@michaeldgraham
Copy link
Collaborator

michaeldgraham commented Nov 1, 2020

Nested mutations

The next step with the experimental mutation API for nested mutations is to generate relationship field arguments for the data input objects. New input object types would be generated for these, containing nested arguments such as create, connect, update, merge, and delete. The types of these mutation-arguments would also be new input objects, containing the now supported where and / or data arguments.

Given the following schema:

  type User {
    idField: ID! @id
    name: String
    birthday: DateTime
    uniqueString: String! @unique
    indexedInt: Int @index
    rated: [Rating]
  }

  extend type User {
    extensionString: String!
  }

  type Rating @relation(name: "RATING", from: "user", to: "movie") {
    user: User
    rating: Int!
    movie: Movie
  }
    
  type Movie {
    id: ID! @id
    title: String! @unique
    genre: MovieGenre @index
    ratedBy: [Rating]
  }

  enum MovieGenre {
    Action
    Mystery
    Scary
  }

Experiemntal augmentation results for the nested mutation support of the User node mutation API would be:

  input _UserData {
    idField: ID
    name: String
    birthday: _Neo4jDateTimeInput
    uniqueString: String
    indexedInt: Int
    extensionString: String
    rated: _UserRatedMutation
  }

  input _UserRatedMutation {
    # Create a Movie Node related with a User node for the RATING relationship
    create: [_CreateUserRatedMovie]
    # connect: ...
  }

  input _CreateUserRatedMovie {
    # require the .rating relationship property because it is non-null on Rating
    rating: Int!
    # require providing data for the Movie to be created and related with a User
    movie: _MovieData!
  }

  input _MovieData {
    title: String!
    ratedBy: _MovieRatedByMutation
  }

  # ...

The translation process would pick these arguments up and recursively generate a Cypher operation composed of Cypher subqueries, to be executed before the generated Cypher for the RETURN statement corresponding to the mutation's GraphQL selection set.

mutation {
  CreateUser(
    data: {
      name: "Michael",
      # new relationship input field
      rated: {
        # create a Movie node and add a relationship with it
        create: {
          rating: 10,
          movie: {
            title: "The Matrix"
          }
        }
      }
    }
  ) {
    # selection set
    name
    rated {
      rating
      movie {
        title
      }
    }
  }
}

Nested mutation input fields

For the input objects generated for relationship field arguments to be added to node mutations:

Node

  • .create
    Creates a node of the related type, and a relationship with it. Arguments would be the same as data.

  • .update
    Updates matching nodes of the related type. Would use where and data sub-arguments.

  • .merge
    Creates or updates a node of the related type, and a relationship with it. Would use where and data sub-arguments.

  • .delete
    Deletes matching nodes of the related type. Arguments would be the same as where.

Relationship

  • .connect
    Creates a relationship with matching nodes of the related type. Arguments would be the same as where.

  • .disconnect
    Deletes relationships with matching nodes of the related type. Arguments would be the same as where.

Possible nested sequences

The following minimal nested combinations would be possible to generate. Any more complex pattern would be composed of pairs of these combinations. Moving forward, each combination needs to be assessed to identify requirements and strategies for translation. Custom errors may be useful / necessary for patterns that don't make sense under certain conditions.

So starting off, one might...

  • Create a node, then...
    create, update, merge, delete, connect, or disconnect...

  • Update a node, then...
    create, update, merge, delete, connect, or disconnect...

  • Delete a node, then...
    create, update, merge, delete, connect, or disconnect...

  • Merge a node, then...
    create, update, merge, delete, connect, or disconnect...

This feature request will be progressively updated with more implementation details regarding generated input types and custom error scenarios.

This feature request is relevant to #89 and #331.

@michaeldgraham
Copy link
Collaborator Author

#608 ;)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant