neo4j-graphql-js icon indicating copy to clipboard operation
neo4j-graphql-js copied to clipboard

Create and connect node with one mutation

Open momegas opened this issue 5 years ago • 4 comments

Hello, i have started using this module and grand stack recently and had a simple question that others may have had.

Can i create a new node and connect it to another one via the generated mutations and using only one call? Maybe i could combine more than one mutations, but i cant find the correct way to do it. Let me give an example.

Say i have the following schema:

type Shop {
  id: ID!
  name: String
  users: [User] @relation(name: "has_user", direction: "IN")
}

type User {
  id: ID!
  name: String
  shop: Shop @relation(name: "has_user", direction: "OUT")
}

I start by creating a new shop using the generated mutation "CreateShop". Then i want to create a new user and connect it the shop i created before with only one graphql call.

I know i could create the user first and then use AddShopUsers or AddUserShop (auto generated queries) but wouldn't it be more efficient to do it with one trip? Also i understand i could create a custom mutation for this but i assume this is common functionality.

I may be missing something because im new at this so please show me the right way 😊

momegas avatar May 27 '19 14:05 momegas

I was wondering the same thing. Some feedback on that would be great!

gcharis avatar May 31 '19 11:05 gcharis

Hello @momegas, @gcharis you can do it manually with a resolver and using cypherMutation method to generate the query for creation, then expand it with your own logic.

Mutation: {
    CreateChat(object, params, ctx, info) {
      const session = driver.session();

      params!.id = uuidV1();

      const { ownerId, hotelId, ...strippedParams } = params!;

      const chatMutationParts: string[] = cypherMutation(
        strippedParams,
        ctx,
        info,
      )[0].split('RETURN');

      const chatMutation = [
        'MATCH (u:User {id: $params.ownerId}), (h:Hotel {id: $params.hotelId})',
        chatMutationParts[0],
        '-[:BELONGS_TO]->(h), (u)-[:OWNS]->(`chat`)<-[:HAS_ACCESS]-(u) \n',
        'RETURN ',
        chatMutationParts[1],
      ].join('');

      return session
        .run(chatMutation, { params })
        .then((result) => {
          session.close();

          const chat = result.records[0].get('chat');

          pubsub.publish(CHAT_CREATED, {
            ChatCreated: chat,
          });

          return chat;
        })
        .catch((error) => {
          console.error('Error: ', error);
        });
    },
  },

We would still wish for it to be easier from the schema itself.

Crodaycat avatar Jul 07 '19 18:07 Crodaycat

Same need here. I would love a solution for that too (without having to write resolvers). But i guess such features will arrive soon such as it does a double MATCH:

- MATCH -> the main purpose of Neo4j -> which is to work with connected data. In 99.9% of cases, when we create a node, it'll be directly linked to others nodes. So when a 'create' mutation is used, in 99.9% it'll be followed by the creation of relations mutations.

- MATCH -> the main purpose of Neo4j-graphql-js -> which is - based on a schema - to propose a ready to use set of query/mutations to directly interact with neo4j db. If we've to develop a custom resolver for each node and each relation because we can't create both at once, the promise of this library is not ready yet.

I would love such feature as much as I love working with these technologies (JS and neo4j) Looking forward for you RETURN

jonasdumas avatar Sep 22 '19 22:09 jonasdumas

https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608

michaeldgraham avatar May 02 '21 04:05 michaeldgraham