Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning results from mutations

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
    })));
};
like image 508
Jim Rootham Avatar asked Oct 18 '22 10:10

Jim Rootham


1 Answers

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.

like image 199
Ahmad Ferdous Avatar answered Jan 04 '23 06:01

Ahmad Ferdous