The Hello World example provided on graphql.org/graphql-js for creating a simple GraphQL implementation is the following:
var { graphql, buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
type Query {
hello: String
}
`);
// The root provides a resolver function for each API endpoint
var root = {
hello: () => {
return 'Hello World!';
}
};
// Run the GraphQL query '{ hello }' and print out the response
graphql(schema, '{ hello }', root).then((response) => {
console.log(response);
});
I'm trying to run an asynchronous function within the resolver, for example a database call, and I can't seem to figure out how to make that work:
What I'm trying to do:
var { graphql, buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
type Query {
data: String
}
`);
// The root provides a resolver function for each API endpoint
var root = {
data: () => {
getData((data) => {
return data; // Returns from callback, instead of from resolver
}
}
};
// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
console.log(response);
});
I've tried to use promises, but there doesn't seem to be a way of escaping the promises without entering a callback. I've also tried various ways of wrapping the asynchronous getData
function to force it to be synchronous, but end up having to return a value from an asynchronous function, same problem. I feel like this can't be this complicated, I mean GraphQL-JS was written by Facebook.
The asynchronous function can be written in Node.js using ‘async’ preceding the function name. The asynchronous function returns implicit Promise as a result.
Note how the function asynchronousCall is void. It returns nothing. Instead, by calling asynchronousCall with an anonymous callback function ( asynchronousCall (function (result) {... ), this function executes the desired actions on the result, but only after the request has completed – when the responseText is available.
The async function helps to write promise-based code asynchronously via the event-loop. Async functions will always return a value. Await function can be used inside the asynchronous function to wait for the promise.
Async functions will always return a value. Await function can be used inside the asynchronous function to wait for the promise. This forces the code to wait until the promise returns a result. Install async from npm in Node.js using the following command:
So this one turned out to be one of those problems you feel really stupid about after you figure it out, but because of how long I spent struggling with it, I'll answer my own question so someone else can hopefully benefit.
It turns out the GraphQL resolver function has to return either a value or a promise that resolves to that value. So what I was trying to do with something like this:
var { graphql, buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
type Query {
data: String
}
`);
// The root provides a resolver function for each API endpoint
var root = {
data: () => {
getData((data) => {
return data; // Returns from callback, instead of from resolver
}
}
};
// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
console.log(response);
});
Can be done with something like this:
var { graphql, buildSchema } = require('graphql');
// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
type Query {
data: String
}
`);
let promiseData = () => {
return new Promise((resolve, reject) => {
getData((data) => {
resolve(data);
});
});
};
// The root provides a resolver function for each API endpoint
var root = {
data: () => {
return promiseData();
}
};
// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
console.log(response);
});
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