My immediate question is why don't the query resolve functions get called?
My suspicion is that there is a problem with the return value from the mutation resolve function (which works). So, what should the return values look like?
A higher level question is: is there a standard way in GraphQL to register a new user and handle the case of the user already existing?
The approach below is to have all the data about the user in the session data and pass back only the data the front end needs.
/**
* graphQL.js
*
* Created by jrootham on 18/04/16.
*
* Copyright © 2016 Jim Rootham
*/
import graphqlHTTP from "express-graphql";
import {
graphql,
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
GraphQLNonNull,
GraphQLBoolean
} from 'graphql';
import {hash} from "bcrypt"
import {connect, User} from "../database/defineDB";
const GraphUser = new GraphQLObjectType({
name: "GraphUser",
description: "A user object",
fields: () => {
return {
name: {
type: GraphQLString,
resolve: (_, __, session) => {
console.log("resolve name", session);
let name = "";
if (session.signedOn) {
return User.findById(session.userId).then (user => {
return user.name;
});
}
console.log("name", name);
return name;
}
},
signedOn: {
type: GraphQLBoolean,
resolve: (_, __, session) => {
return session.signedOn;
}
},
existed: {
type: GraphQLBoolean,
resolve: (_, __, session) => {
return session.existed;
}
}
}
}
});
const query = new GraphQLObjectType({
name: 'Queries',
fields: () => {
return {
graphUser: {
type: GraphUser
}
}
}
});
const mutation = new GraphQLObjectType({
name: 'Mutations',
description: "Modification actions",
fields() {
return {
registerUser: {
type: GraphUser,
args: {
name: {
type: new GraphQLNonNull(GraphQLString)
},
password: {
type: new GraphQLNonNull(GraphQLString)
}
},
resolve(_, args, session) {
console.log("resolve", args);
User.findOne({where:{name:args.name}}).then(user => {
console.log("After find", user);
if (user === null) {
const getHash = new Promise(
resolve => {
hash(args.password, 10, (err, hash) => {
resolve(hash);
});
}
);
const result = getHash.then(hash => {
connect.models.user.create({
name: args.name,
password: hash
}).then(user => {
session.userId = user.id;
session.signedOn = true;
session.existed = false;
console.log("session user", session.userId);
return user;
});
console.log(result);
return result;
});
}
else {
session.userId = 0;
session.signedOn = false;
session.existed = true;
console.log("existed");
return GraphUser;
}
});
}
}
}
}
});
const schema = new GraphQLSchema({
query: query,
mutation: mutation
});
export const useGraphQL = app => {
app.use('/graphql', graphqlHTTP(request =>({
schema: schema,
context: request.session,
formatError: error => ({
message: error.message,
locations: error.locations,
stack: error.stack
}),
graphiql:true
})));
};
why don't the query resolve functions get called?
Your root query field graphUser
doesn't get resolved.
const query = new GraphQLObjectType({
name: 'Queries',
fields: () => {
return {
graphUser: {
type: GraphUser
// TODO Add a resolve function here
}
}
}
});
My suspicion is that there is a problem with the return value from the mutation resolve function (which works). So, what should the return values look like?
If you use Promise
, Your mutation's resolve
function should return a Promise (it doesn't return now) and should use resolve(result)
instead of return result
. If user already exists, just return the existing user object instead of type GraphUser
.
A higher level question is: is there a standard way in GraphQL to register a new user and handle the case of the user already existing?
GraphQL itself does not have a standard way of handling user registration. You just need a mutation for user registration. In the mutation's resolve function, whether the user already exists is checked. If exists, the mutation can return error. Otherwise, the user is registered and the newly created user object is returned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With