1

I'm new to graphql and node so sorry if this is really simple but I'm trying to perform a mysql query so that the query response is returned by graphql for the client to read from. The problem I'm running into is that because node-mysql does query asynchronously, I can't get the query response directly.

After some tinkering I figured it out, new code:

var root = {
    login: function({username, password}) {
        var s = `select password from users where username='${username}'`;
        var result = sql.query(s);
        return result.then(response => {
            return password == response[0].password
        });
}

Here is the function definition for sql.query

exports.query = function(s, callback) {
    var promise = new Promise((resolve, reject) => {
        con.query(s, function(err, response) {
            if (err) throw err;
            resolve(response);
    });
});
return promise;

Graphql now return that response is not defined.

2 Answers 2

5

I personally use mysql, but shouldn't be too much of a difference.

So I do it like this:

exports.getUser = ({ id }) => {
  return new Promise((resolve, reject) => {
    let sql = `select * from users u where u.user_id = ?`;
    sql = mysql.format(sql, [id]);
    connection.query(sql, (err, results) => {
      if (err) reject(err);
      resolve(results);
    });
  });
};

Wrap the query around a Promise, which resolves when the query is done.

Then in the resolve of a field, you just call .then on the promise and do whatever you want.

const viewerType = new GraphQLObjectType({
  name: 'Viewer',
  fields: () => ({
    user: {
      type: userType,
      args: {
        id: {
          type: GraphQLInt,
        },
      },
      resolve: (rootValue, args) => {
        return getUser({ id: args.id }).then(value => value[0]);
      },
    },
  }),
});
Sign up to request clarification or add additional context in comments.

4 Comments

I updated my code to do it how yours does and now graphql shows that response is not defined. Also, is there a difference between how you defined the resolve function vs how I did? I don't have anywhere in my code an instantiation of GraphQLObjectType.
Your .then is not returning right. It should probably be .then((response) => password == response[0].password);
Yup, just fixed it, thank you so much! On a side note, what about the difference between how you defined the resolver and how I did it? Does it matter?
Hmm, not sure actually. But I think the difference is that you're hard coding in the field. So, if you want reuse the login somewhere else, creating an objecttype is a good way to go about it. But in your case above where you just verify for login only in one place with true and false, it's not necessary to create a new type.
0

I appreciate that this is an old post but I've found this topic somewhat confusing and have been investigating different approaches, both which are shown here. One is a bit less verbose then the other (getQuery). I include the code for a mutation which although largely irrelevant to this topic demonstrates how none of this promise complication applies to returning the result of a mutation, just saying.

The documentation describes another approach called promise wrappers https://github.com/sidorares/node-mysql2#using-promise-wrapper. In my case this would have needed a top level await which didn't really fit in with my needs although there are all kinds of workarounds, but I just wanted the simplest possible solution to a simple problem.

resolver.ts

import db from "db";
    
    // this is one way of doing it
    const getQuery = async (sql: string) => {
      const [rows] = await db.promise().query(sql);
      return rows;
    };
    
    // and this is another
    const getQuery2 = (sql: string) => {
      return new Promise((resolve, reject) => {
        db.query(sql, (error, results) => {
          if (error) return reject(error);
          return resolve(results);
        });
      });
    };
    
    export const resolvers = {
      Query: {
        getUsers: () => getQuery("SELECT * FROM `users`"),
      },
      Mutation: {
        userLogin: (_, { email, password }) => {
          return {
            __typename: "UserLoginResponse",
            status: "success",
            jwt: "abc123",
          };
        },
      },
    };


db.ts

import mysql2 from "mysql2";

console.log("connecting to RDS db:", process.env.DB_BOOK_IT_HOST);

export const db = mysql2.createConnection({
  host: process.env.DB_BOOK_IT_HOST,
  user: process.env.DB_BOOK_IT_USER,
  password: process.env.DB_BOOK_IT_PASSWORD,
  database: process.env.DB_BOOK_IT_DATABASE,
});

export default db;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.