Passing Objects as Argument to GraphQL Mutation (graphql-request)
Asked Answered
D

1

5

I have a very basic graphql mutation in the frontend that I send to my backend. I am using this code on the by graphql-request as a guide.

With primitives it works:

const mutation = gql`
    mutation EditArticle($id: ID!, $title: String) {
      editArticle(id: $id, title: $title) {
        id
      }
    }
  `

Now I'd like to also be able to mutate some meta data about the article, stored in a meta object inside the article:

...,
title: "Hello World",
meta: {
 author: "John",
 age: 32,
 ...
}

So my question is: How do I pass over non-primitive object types as arguments to mutations when making the request from the frontend, using graphql-request?

I tried something like this already:

const Meta = new GraphQLObjectType({
    name: "Meta",
    fields: () => ({
      id: { type: GraphQLID },
      name: { type: GraphQLString },
      age ....
    }),
  })
   
const mutation = gql`
    mutation EditArticle($id: ID!, $title: String, $meta: Meta) { //??? I don't seem to get what goes here? 
      editArticle(id: $id, title: $title, meta: $meta) {
        id
      }
    }
  `

I also tried it with GraphQLObjectType, but I think I am going wrong here (since this is the frontend).

PS: I looked at this answer, but I didn't understand / believe the solution there might be incomplete.

Dinka answered 20/12, 2020 at 14:55 Comment(4)
Look in your schema what the types of the editArticle arguments are. Most likely it should be something like MetaInput. It needs to be an input type, not an output one.Apt
Thanks a lot, I think I understand now. So the MetaInput type is something I define on the server, but on the client I can just write that it's of the type MetaInput and there's no need to define this again on the client, as I understand now?Dinka
Yes, if you're using express-graphql, though of course the server side is implementation dependent (and you don't necessarily need to construct a new GraphQLInputObjectType yourself - you might just parse a schema definition or something). But on the frontend, where you're defining the query, you'd just refer to it by name, you don't have to do anything extra.Apt
Ok, I think this was the bit that had me confused!! Thank you (so!) much. If you just write that as an answer, I would definitely accept that :)Dinka
A
8

You need to define the input object type in your serverside schema, as something like

input MetaInput {
  name: String
  author: String
  release: Date
}

and use it in the editArticle definition

extend type Mutation {
  editArticle(id: ID!, title: String, meta: MetaInput): Article
}

Then you can also refer to the MetaInput type in the clientside definition of your mutation EditArticle.

Apt answered 20/12, 2020 at 19:54 Comment(1)
Thanks a lot, that's very helpful!Dinka

© 2022 - 2024 — McMap. All rights reserved.