Backend with Express(JS) - GraphQL mutation function doesn't work - javascript

I don't get the request variable in the mutation GraphQL on the backend. I don't understand why it doesn't work.
I get the next error:
"Cannot destructure property 'name' of 'undefined' as it is undefined."
That mutation I make in Apollo Studio:
mutation Mutation($createOwnerName: String) {
createOwner(name: $createOwnerName)
}
My variables in Apollo Studio:
{
"createOwnerName": "John"
}
My backend with Express
schema.js:
const { buildSchema } = require("graphql");
const schema = buildSchema(`
type Mutation {
createOwner(name: String): String
}
`);
module.exports = schema;
resolvers.js:
const resolvers = {
Mutation: {
createOwner: ({name}) => {
console.log('createOwner name', name)
return name
}
}
}
server.js:
const { createServer } = require("http");
const express = require("express");
const { execute, subscribe } = require("graphql");
const { ApolloServer } = require("apollo-server-express");
const { SubscriptionServer } = require("subscriptions-transport-ws");
const { makeExecutableSchema } = require("#graphql-tools/schema");
const typeDefs = require("./graphql/schema.js");
const resolvers = require("./graphql/resolvers.js");
require("dotenv").config();
const mongoose = require("mongoose");
// mongoose
mongoose
.connect(process.env.DB_HOST, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("MongoDB connected"))
.catch((err) => console.log(err));
(async () => {
const PORT = 3033;
const app = express();
const httpServer = createServer(app);
app.get("/rest", function (req, res) {
return res.json({ data: "rest" });
});
const schema = makeExecutableSchema({ typeDefs, resolvers });
const server = new ApolloServer({
schema,
});
await server.start();
server.applyMiddleware({ app });
SubscriptionServer.create(
{ schema, execute, subscribe },
{ server: httpServer, path: server.graphqlPath }
);
httpServer.listen(PORT, () => {
console.log(
`🚀 Query endpoint ready at http://localhost:${PORT}${server.graphqlPath}`
);
console.log(
`🚀 Subscription endpoint ready at ws://localhost:${PORT}${server.graphqlPath}`
);
});
})();

You are destructuring the wrong argument. Arguments are in that order:
Parent value
Argument values
Context
GraphQL Resolve Info
Destructure the second parameter:
const resolvers = {
Mutation: {
createOwner: (parent, {name}) => {
console.log('createOwner name', name)
return name
}
}
}

Related

GraphQL HTTP: "Cannot return null for non-nullable field Mutation.register."

I am trying to mutate in GraphQL to create a new user but I get the error of
Cannot return null for non-nullable field Mutation.register.
Screenshot of operation, variable and response here.
graphql/schema/schema.js
const{ buildSchema } = require('graphql');
const schema = buildSchema(`
type User {
_id: ID!
email: String!
username: String!
token: String!
createdAt: String!
}
input RegisterInput{
username: String!
password: String!
confirmPassword: String!
email: String!
}
type Query {
user(id: ID!): User
}
type Mutation {
register(registerInput: RegisterInput): User!
}
schema {
query: Query
mutation: Mutation
}
`)
module.exports = schema;
graphql/resolvers/user.js
const User = require('../../models/user.js');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const SECRET_KEY = 'oPXA96op!u%,`:}eT^.!|hvXohA~fa';
module.exports = {
Mutation: {
async register(
_,
{
registerInput: { username, email, password, confirmPassword}
},
context,
info
) {
password = await bcrypt.hash(password, 12);
const newUser = new User({
email,
username,
password,
createdAt: new Date().toISOString
});
const res = await newUser.save();
const token = jwt.sign({
id: res.id,
email: res.email,
username: res.username
}, SECRET_KEY, { expiresIn: '1h'});
return{
...res._doc,
id: res._id,
token
};
}
}
};
graphql/resolvers/index.js
const postResolver = require('./post');
const userResolver = require('./user');
const resolvers = {
Mutation: {
...userResolver.Mutation
},
...postResolver
}
module.exports = resolvers;
server.js
const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
const mongoose = require('mongoose');
const cors = require('cors');
const { graphqlHTTP } = require('express-graphql');
const MONGODB = '';
const schema = require('./graphql/schema');
const resolvers = require('./graphql/resolvers');
const PORT = 4000;
const server = new ApolloServer({ schema, resolvers });
mongoose.connect(MONGODB);
mongoose.connection.once('open', function() {
console.log('Connected to the Database.');
});
mongoose.connection.on('error', function(error) {
console.log('Mongoose Connection Error : ' + error);
});
const app = express();
app.use(cors());
let apolloServer = null;
async function startServer() {
apolloServer = new ApolloServer({
schema,
resolvers,
});
await apolloServer.start();
apolloServer.applyMiddleware({ app });
}
startServer();
app.use("/graphql", graphqlHTTP({
schema: schema,
rootValue: resolvers,
graphiql: true
}));
app.listen(PORT, function() {
console.log(`Server listening on port ${PORT}.`);
});
I have checked many previous posts about this mutation error but none have seen to be resolved, and also have done many modifications to the schema/resolver but has not worked. I have also posted on the GraphQL Discord for help, but have had no luck. I tried changing the server.js but it affected my queries from running so I reverted.
/graphql/resolvers/post.js
const Post = require('../../models/post.js');
const { GraphQLDateTime } = require ('graphql-iso-date');
const customScalarResolver = {
Date: GraphQLDateTime
};
function posts() {
return Post.find({});
}
function post(args) {
return Post.findById(args.id)
}
function createPost(args) {
let post = new Post(args.postInput);
return post.save();
}
function deletePost(args) {
return Post.findByIdAndRemove(args.id);
}
function updatePost(args) {
return Post.findByIdAndUpdate(args.id, args.postInput, { new: true });
}
module.exports = { posts, post, createPost, deletePost, updatePost, customScalarResolver}

Server Error while using Graphql Playground

I have been following the www.howtographql.com tutorials but i am stuck as i am not able to add authorization token in http headers. As soon as i write the authorization token it gives an error - 'Server cannot be reached'
index.js
const { ApolloServer } = require('apollo-server');
const { PrismaClient } = require('#prisma/client');
const fs = require('fs');
const path = require('path');
const { getUserId } = require('./utils');
const Query = require('./resolvers/Query');
const Mutation = require('./resolvers/Mutation');
const User = require('./resolvers/User');
const Link = require('./resolvers/Link');
const prisma = new PrismaClient();
const resolvers = {
Query,
Mutation,
User,
Link
}
const server = new ApolloServer({
typeDefs: fs.readFileSync(
path.join(__dirname, 'schema.graphql'),
'utf-8'
),
resolvers,
context:({ req }) => {
return {
...req,
prisma,
userId: req && req.headers.authorization ? getUserId(req) : null
};
}
});
server.listen()
.then(({ url }) => console.log(`Server is running on ${url}`)
);

GraphQL Subscription Configuration Error

Good day, I am trying to make a simple app where , when user add any product subscriber will trigger and event and send back the product.I've implemented some code with help of google everything is working excepts subscriber, When I browse graphiql in my browser I see some error like Expected { query: { kind: "Document", definitions: [Array], loc: [Object] }, mutation: { Query: [Object], Mutation: [Object], Subscription: [Object], Upload: Upload } } to be a GraphQL schema.
, Here is my code below ,
Server main index.js file
const express = require('express')
const morgan = require('morgan')
const cors = require('cors')
const bodyParser = require('body-parser')
const {ApolloServer, gql} = require('apollo-server-express');
const {createServer} = require('http');
const {execute, subscribe} = require('graphql');
const {makeExecutableSchema} = require('#graphql-tools/schema');
const {PubSub} = require('graphql-subscriptions');
const {SubscriptionServer} = require('subscriptions-transport-ws');
const typeDefs = require("./GraphQLSchema/typeDef")
const resolvers = require("./GraphQLSchema/resolvers")
const myGraphQLSchema = require('./GraphQLSchema');
const coreRouting = require("./routes")
require('dotenv').config()
const app = express()
app.use(bodyParser.json())
//app middleware
app.use(morgan('dev'));
//app.use(cors())
const {PrismaClient} = require("#prisma/client")
const prisma = new PrismaClient();
async function checkPrismaConnection() {
const obj = {
include: {transactions: true}
}
try {
// const result = await prisma.product.findMany({
// include: {transactions: false}
// });
const result = await prisma.transaction.findMany();
console.log(result);
} catch (e) {
console.log(e);
}
}
//checkPrismaConnection();
app.use(coreRouting);
app.get('/test/route', (req, res) => res.send('Hello World!'))
const serverPort = process.env.PORT || 9000
app.use('/graphql', bodyParser.json());
const apolloServer = new ApolloServer(
{
typeDefs,
resolvers,
context: ({req}) => ({req, pubsub})
});
apolloServer.applyMiddleware({app});
const pubsub = new PubSub();
const server = createServer(app);
//const schema = makeExecutableSchema({typeDefs, resolvers});
server.listen(serverPort, () => {
new SubscriptionServer({
execute,
subscribe,
pubsub,
schema: {
query: typeDefs,
mutation: resolvers,
},
graphiql: true
}, {
server: server,
path: '/graphql',
});
});
typeDefs Code
const {gql} = require("apollo-server-express");
module.exports = gql`
type Post{
body: String!
}
type Product{
id: Int!
name: String!
transactions:[Transaction]!
}
type Transaction{
id: Int!
quantity: Int!
time: String!
}
input ProductInput{
name: String!
}
type Query {
getPosts: [Post]
products: [Product]
product(id: ID!): Product
}
type Mutation {
createProduct(productInput: ProductInput):Product!
}
type Subscription {
newProduct: Product!
}
`
Resolvers Code
const {helperMethodForFetcingProducts, helperMethodForCreateProduct} = require("../../helper");
const {relationalKeyword} = require("../../helper/keyword");
module.exports = {
Query: {
getPosts() {
return [{"body": "First Post"}, {"body": "2nd Post"}, {"body": "3rd Post"}]
},
products: async function () {
return helperMethodForFetcingProducts(relationalKeyword, false);
},
product: async function (_, {id}) {
console.log(_, id);
return helperMethodForFetcingProducts(relationalKeyword, true, parseInt(id));
}
},
Mutation: {
createProduct: async (_, {productInput: {name}}, {pubsub}) => {
let getProductFromMethod = await helperMethodForCreateProduct(name);
pubsub.publish('Proudct_Added', {
newProduct: getProductFromMethod
})
return getProductFromMethod;
}
},
Subscription: {
newProduct: {
subscribe: (_, __, {pubsub}) => pubsub.asyncIterator('Proudct_Added')
}
}
}
My Error
Since I am new in graphQL I don't understand the issue actually.

Context for GraphQl resolvers undefined

I'm new to graphQL but for whatever reason is seems like my context parameter is undefined in my resolver. Here is how I am setting up the server:
index.js
import express from 'express';
import path from 'path';
import { fileLoader, mergeTypes, mergeResolvers } from 'merge-graphql-schemas';
import { ApolloServer } from 'apollo-server-express';
import models from './models';
const typeDefs = mergeTypes(fileLoader(path.join(__dirname, './schema')));
const resolvers = mergeResolvers(fileLoader(path.join(__dirname, './resolvers')));
const PORT = 4000;
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.applyMiddleware({ app });
models.sequelize.sync({force: true}).then(x => {
app.listen({ port: PORT }, () =>
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
);
});
Example Resolver:
export default {
Query: {
getUser: (parent, { id }, { models }) => models.User.findOne({ where: { id } }),
allUsers: (parent, args, { models }) => models.User.findAll(),
},
Mutation: {
createUser: (parent, args, { models }) => models.User.create(args),
},
};
When I try to do the createUser mutation I get the error: Cannot read property 'User' of undefined.
Which means my context object parameter is undefined. Any help is appreciated, GraphQL setup has been a bit confusing for me.

MongoDB Exit code connetion

I am having an error with mongoose.
This is my code
const { ApolloServer } = require("apollo-server");
const gql = require("graphql-tag");
const mongoose = require("mongoose");
const { MONGODB } = require("./config");
const typeDefs = gql `
type Query {
sayHi: String!
}
`;
const resolvers = {
Query: {
sayHi: () => "Hello from GraphQL",
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
mongoose
.connect(MONGODB, {
useNewUrlParser: true,
})
.then(() => {
console.log("Connection to Db established sucessfully!");
return server.listen({
port: 5000,
});
})
.then((res) => {
console.log(`Server running at ${res.url}`);
});
And I am getting this error on bash.
The use of Unhandled Promise Rejection is deprecated. The next time node's will exit with an exit code of non-zero.
Can someone please tell me how to solve it with a code example.
I think the error is in the mongoose.connect(()) line.

Categories

Resources