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
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}
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}`)
);
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.
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.
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.