Search code examples
expressmongooseschemagraphqlgraphiql

Trying to do Graphql mutation on Graphiql


So I am trying to carry out a mutation on graphiql but keep getting this error: enter image description here

here is my setup:

Schema:

import { GraphQLInt, GraphQLString, GraphQLList, GraphQLObjectType, GraphQLNonNull, GraphQLSchema, } from 'graphql';
import * as _ from 'lodash';

import mongoose from 'mongoose';
import messageModel from './models/messages';
import userModel from './models/users';
import groupModel from './models/groups';


export const Schema =[`
scalar Date

type  Group {
  id: String!,
  name: String,
  created_at:Date!,
  users: [User],
  messages: [Message]
}

type User {
  id: String!,
  username: String!,
  email: String!,
  password: String!,
  location: String!,
  groups: [Group],
  friends: [User]
}

type Message {
  id: String!,
  to: Group!,
  from: User!,
  message: String!,
  date: Date!
}

type Query {
  user(email: String, id: Int): User
  messages(groupId: Int, userId: Int): [Message]
  group(id: Int!): Group
}

type Mutation {
  createMessage(groupId: String!, userId: String!, text: String!): Message
  createUser(username: String!, email: String! password: String!, location:String!): User
}

schema {
  query:Query
  mutation: Mutation
}
`]

export default Schema;

Mongoose schema and model for user:

import mongoose from 'mongoose';
const Schema = mongoose.Schema;

const userSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true
    },
    location: {
        type: String,
        required: true,
    },
    groups: [{
        type: Schema.Types.ObjectId, ref: 'group'
    }],

    friends: [{
        type: Schema.Types.ObjectId, ref: 'user'
    }]
});

let userModel = mongoose.model('user', userSchema);
export default userModel;

here are the resolvers:

import GraphQLDate from 'graphql-date';
import groupModel from './models/groups';
import messageModel from './models/messages';
import userModel from './models/users';

export const Resolvers = {
    Date: GraphQLDate,
    Query: {
        group(_, args) {
            return groupModel.find({ $where: args }).exec((err, groups) => {
                return groups;
            })
        },
        messages(_, args) {
            return messageModel.find()
        },
        user(_, args) {
            return userModel.findOne()
        },
    },
    Mutation: {
        createMessage(_, { text, userId, groupId }) {
            return messageModel.create({
              from:userId,
              message:text,
              to:groupId,
            });
          },
          createUser(_, { username, email, password, location}) {
            return messageModel.create({
                username:username,
                email: email,
                password: password,
                location: location
            });
          },
    },
    Group: {
        users(group) {
            return group.getUsers();
        },
        messages(group) {
            return messagemodel.findAll({
                where: { groupId: group.id },
                order: [['createdAt', 'DESC']],
            });
        },
    },
    Message: {
        to(message) {
            // return messageModel.find({id:message.id}).populate('to').exec((err,message) => {
            //     return message.to;
            // })
            return messageModel.findOne({ '_id': message.id }).populate('to').exec((err, message) => {
                if (err) return err;
                return message
            })
        },
        from(message) {
            return message.getUser();
        },
    },
    User: {
        groups(user) {
            return user.getGroups();
        },
        friends(user) {
            return user.getFriends();
        },
    },
};
export default Resolvers;

and here is my setup for server.js:

if (!process.env.NODE_ENV) process.env.NODE_ENV = "dev";
import express from 'express';

import { graphqlExpress, graphiqlExpress } from 'graphql-server-express';
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
import bodyParser from 'body-parser';
import { createServer } from 'http';

import Schema from './src/schema';
import Resolvers from './src/resolvers';

import mongoose from 'mongoose';

import config from './config';
var db = process.env.DB || config.DB[process.env.NODE_ENV];
var PORT = config.PORT[process.env.NODE_ENV];
const app = express();

mongoose.connect(db, function (err) {
  if (!err) {
    console.log(`connected to the Database: ${db}`);
  } else {
    console.log(`error connecting to the Database ${err}`);
  }
});

const executableSchema = makeExecutableSchema({
  typeDefs: Schema,
  resolvers: Resolvers,
});

app.use('/graphql', bodyParser.json(), graphqlExpress({
  schema: executableSchema,
  context: {}, // at least(!) an empty object
}));

app.use('/graphiql', graphiqlExpress({
  endpointURL: '/graphql',
}));

const graphQLServer = createServer(app);

graphQLServer.listen(PORT, () => console.log(`GraphQL Server is now running on http://localhost:${PORT}/graphql`));

So I am trying to learn Graphql to build an api, but finding it hard with so many different tutorials on how to do things. Can anyone tell me or point me in the right direction as to what I'm doing wrong?


Solution

  • You are saying the username parameter is type 'username' which isn't a valid type (same with email, password, and location). Assuming username, email, password, and location are strings and required, the mutation should look something like this:

    mutation createUser(username: String!, $email: String!, $password: String!, $location: String!) {
       createUser(username: $username, email: $email, password: $password, location: $location {
          username
          email
          password
          location
        }
    }