4

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.

R. Kohlisch
  • 2,823
  • 6
  • 29
  • 59
  • 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. – Bergi Dec 20 '20 at 17:30
  • 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? – R. Kohlisch Dec 20 '20 at 17:39
  • 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. – Bergi Dec 20 '20 at 17:43
  • 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 :) – R. Kohlisch Dec 20 '20 at 17:53

1 Answers1

6

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.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375