1
votes

I'm new with GraphQL and I'm trying to do a mutation to delete an article from my database but I can't figure out how. I'm using Node.js, Mongoose and GraphQL.

This is the mutation on my schema.

const Mutation = new GraphQLObjectType({
  name: 'Mutation',
  description: 'Articles Mutations',
  fields: () => ({
    remove: {
      type: articleType,
      description: 'Deletes an article by id',
      args: {
        id: {
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: (value, {id}) => {
        return db.Article.findOneAndRemove({_id: new ObjectId(id)});
      }
    }
  })
});

And this is the query I'm using when calling the API to delete an article.

export const DELETE_ARTICLE_QUERY = (id) => (`{
  remove(id: "${id}") {
    id
    author
    content
    published
    tags
    title
    excerpt
  }
}`);

What am I doing wrong?

I'm getting a 400 Bad Request error. Message: "Cannot query field "remove" on type "Mutation"."

1
When asking a question like this, it's helpful to provide as much details as possible. For example: whether or not GraphQL or node are throwing any errors when you run the query, and what the errors say.Daniel Rearden

1 Answers

2
votes

When making a GraphQL request, it's best to always specify the type of operation you are performing (query or mutation). When you fail to do so, GraphQL assumes you are making a query, which isn't the case here. You didn't specify whether you were seeing any errors, but I'd wager GraphQL is returning something like cannot query field remove on Query.

Modify DELETE_ARTICLE_QUERY to include the operation:

export const DELETE_ARTICLE_QUERY = (id) => (`mutation {

It's good practice to include an operation name for debugging purposes, so you could also say:

export const DELETE_ARTICLE_QUERY = (id) => (`mutation DeleteArticle {

Edit: Based on the error you provided, it sounds like the schema object is not set up correctly. It should look something like this:

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: "WhateverNameYouWantForQuery",
    fields: {
      // each query is a property here
    }
  }),
  mutation: new GraphQLObjectType({
    name: "WhateverNameYouWantForMutation",
    fields: {
      // each mutation is a property here
    }
  }),
});

If you define your mutations as a separate variable (Mutation), you would assist the value of the mutation property as that variable:

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    // query props
  }),
  mutation: Mutation
  }),
});

Here's a working example you can run out of the box and play around with. After starting the server, you can go to http://localhost:3000/graphql in your browser to access the GraphiQL interface and play around with potential queries/mutations on there.

const graphqlHTTP = require('express-graphql');
const app = require('express')();
const {
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLNonNull,
  GraphQLString,
  GraphQLList
} = require('graphql');

const articleType = new GraphQLObjectType({
  name: 'Article',
  fields: {
    title: {
      type: GraphQLString,
    },
  },
});

const Mutation = new GraphQLObjectType({
  name: "RootMutationnnnn",
  fields: () => ({
    remove: {
      type: articleType,
      args: {
        id: {
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: (value, {id}) => {
        return {title: 'Testing a delete'};
      }
    }
  })
});

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: "RootQueryyyyy",
    fields: {
      articles: {
        type: new GraphQLList(articleType),
        resolve: () => {
          return [{title: 'Test title'}, {title: 'Test title'}];
        }
      }
    }
  }),
  mutation: Mutation
});

const root = {};

app.post('/graphql', graphqlHTTP({
  schema,
  rootValue: root,
  graphiql: false,
}));

app.get('/graphql', graphqlHTTP({
  schema,
  rootValue: root,
  graphiql: true,
}));

app.listen(3000, function(){
  console.log('listening on port 3000');
});