GraphQL - How retrieve id of previous mutation, during query of multiple mutations
Asked Answered
C

1

3

i would like run multiple mutations in the same query.

In the example below, i create an order and after i create a product record, concerning previously created.

I must have 2 mutations.

First, i insert an order. In output, i retrieve among others, idorder.

Then, i insert an product. This product

mutation {
  createOrder(input: {
    order: {
      ordername: "My order"
    }
  }) {
    order {
      idorder
      ordername
    }
  },
  createProduct(input: {
    product: {
      quantity: 3
      idrefproduct: 25 # link to refProduct
      idorder: XXXX         # how can i retrieve idorder from output of createOrder above ? πŸ€”
    }
  }) {
    product {
      idproduct
    }
  }
}

Real example with SQL structure :


user(iduser, othersFields);
scenarios(idscenario, iduser, name, otherFields);

cultA(idcultA, idscenario, ...); // this table need of idscenario field
cultB(idcultB, idscenario, ...); // this table need of idscenario field
cultC(idcultC, idscenario, ...); // this table need of idscenario field

how can i retrieve idorder from output of createOrder above ? πŸ€”

It is possible ?

If i forgot some informations, don't hesitate.

Thanks in advance.

EDIT :

  • With PostGraphile, plugin "postgraphile-plugin-nested-mutations" or "custom mutations" (with PL PGSQL function)
  • Without PostGraphile, a resolver as the example of @xadm permits this particular nested mutation.
Cauley answered 17/4, 2020 at 10:2 Comment(2)
probably looking for "nested mutations" – Joel
I saw with "nested mutations", however i didn't found for my use case. I would like really retrieve the id generated in order, because i need it for run execute insertions in product and other tables in the same query. Had you already use variables in "nested mutations" ? – Cauley
J
1

IMHO you can search for "nested mutations" - not described here, you'll easily find examples/tutorials.

Proposed DB structure (n-to-n relation):

order{orderID,lines[{orderLineID}] } > 
  order_line{orderLineID, productID, anount, price} > 
    product {productID}

... created in nested mutations (in reverse order product>order_line>order)

Product don't need orderID, but when you ask for it [in product resolver]

query product(id) {
  id
  orderedRecently {
    orderID
    date
    price
  }
}

... you can simply get it (or rather many - array) from orderLines and orders tables [using simple SQL query - where price will be read from orderLines]

orderedRecently resolver can get product id from parent object (usually 1st param)

Of course you can (and should) return data as order and orderLine types (to be cached separately, normalized):

query product($id: ID!) {
  product(id: $id) {
    id
    orderedRecently {
      id
      date
      orderLine {
        id
        amount
        price
      }
    }
  }
}

where type orderedRecently: [Order!] - array can be empty, not eordered yet

update

I slightly misunderstood your requirements (naming convention) ... you already have proper db structure. Mutation can be 'feeded' with complex data/input:

mutation {
  createOrder(input: {
    order: {
      ordername: "My order"
      products: [
        {
          quantity: 3
          idrefproduct: 25 
        },
        {
          quantity: 5
          idrefproduct: 28
        }
      ]
    }
  }) {
    order {
      id
      ordername
      products {
        id
        idrefproduct    
        quantity
      }
    }
  }
}

Your product is my orderLine, idrefproduct is product.

createOrder creates/inserts order and then use its id for creation of product records (order.id, idrefproduct and quantity). Resolver can return only order id or structured data (as above).

Joel answered 17/4, 2020 at 14:15 Comment(8)
Thanks for your help, you spend time for me, it's nice. However, i don't understand many ideas. My example is an example. I wanted to retrieve "id of order" because after, i'm going to use it in multiple insertions in multiples tables (tables A, B, C, ...). In your explanation, you write "query" but we talk about mutations, i'm lost. – Cauley
Examples on the net doesn't match with my use case, IMHO. Often, i see "i insert article, and then i insert inside, sub object tagsArticles. and it's good !" – Cauley
As I wrote ... it's not explanation about nested mutations ... yes, it's good as tag doesn't need article_id ... your product doesn't need order_id, the same ... redesign tables/relations ... or show structures/relations – Joel
Thank for your patience. I'm not expert in graphQL. I'm going to edit my first post now, with table and relations. – Cauley
Hello @xadm, and thanks for your help and it's true, my example isn't explicit. I read your updated response. I understood better. I will study that and i will give feedback tomorrow. Thanks again. Have a nice sunday. gql mutation { createOrder(input: { order: { ordername: "My order" products: [ { ... }, ], cultA: [ { ... }, ] } }) { order { id ordername products { id idrefproduct quantity } } } } – Cauley
Thanks again. I understood your example. With a plugin in PostGraphile, i succeeded to reproduce the same type of structure of your example ! I'm going to edit my original post. – Cauley
@Cauley if it helped upvote my answer ... you can answer your own question and accept it – Joel
done on your first response ! however, i had this message : "Thanks for the feedback! Votes cast by those with less than 15 reputation are recorded, but do not change the publicly displayed post score." – Cauley

© 2022 - 2024 β€” McMap. All rights reserved.