GraphQL:完成来自 JSON 文件源的查询
GraphQL: fulfill query from JSON file source
我刚刚开始使用 GraphQL,我想要一个使用磁盘上的 JSON 文件作为数据源的解析器。到目前为止我得到的结果导致 GraphQL return null
.
我该怎么做,为什么下面的方法不起作用?
var schema = buildSchema(`
type Experiment {
id: String
trainData: String
goldData: String
gitCommit: String
employee: String
datetime: String
}
type Query {
# Metadata for an individual experiment
experiment: Experiment
}
schema {
query: Query
}`);
var root = {
experiment: () => {
fs.readFile('./data/experimentExample.json', 'utf8', function(err, data) {
if (err) throw err;
console.log(data);
return JSON.parse(data);
});
}
};
const app = express();
app.use('/graphql', graphqlHTTP({
rootValue: root,
schema: schema,
graphiql: true
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
您传递给 readFile
的回调函数异步运行,这意味着 return 从中获取值不会执行任何操作 - readFile
调用的函数是内部已完成执行,并在回调完成时 return 编辑了一个值(空)。
根据经验,在处理 GraphQL 时,您应该远离回调——您的解析器应该始终 return 一个值或一个最终会解析为一个值的 Promise。
幸运的是,fs
有一个异步读取文件的方法,所以你可以这样做:
const root = {
experiment: () => {
const file = fs.readFileSync('./data/experimentExample.json', 'utf8')
return JSON.parse(file)
}
};
// or even cleaner:
const root = {
experiment: () => JSON.parse(fs.readFileSync('./data/experimentExample.json', 'utf8'))
};
再举一个例子,下面是使用 Promise 的方法:
// using Node 8's new promisify for our example
const readFileAsync = require('util').promisify(fs.readFile)
const root = {
experiment: () => readFileAsync('./data/experimentExample.json', {encoding: 'utf8'})
.then(data => JSON.parse(data))
};
// Or with async/await:
const root = {
experiment: async () => JSON.parse(await readFileAsync('./data/experimentExample.json', {encoding: 'utf8'}))
};
当然没有必要对 readFile 进行承诺,因为您已经有了可用的异步方法,但这让您了解了如何使用 Promises,而 GraphQL 很乐意与之合作。
我刚刚开始使用 GraphQL,我想要一个使用磁盘上的 JSON 文件作为数据源的解析器。到目前为止我得到的结果导致 GraphQL return null
.
我该怎么做,为什么下面的方法不起作用?
var schema = buildSchema(`
type Experiment {
id: String
trainData: String
goldData: String
gitCommit: String
employee: String
datetime: String
}
type Query {
# Metadata for an individual experiment
experiment: Experiment
}
schema {
query: Query
}`);
var root = {
experiment: () => {
fs.readFile('./data/experimentExample.json', 'utf8', function(err, data) {
if (err) throw err;
console.log(data);
return JSON.parse(data);
});
}
};
const app = express();
app.use('/graphql', graphqlHTTP({
rootValue: root,
schema: schema,
graphiql: true
}));
app.listen(4000);
console.log('Running a GraphQL API server at localhost:4000/graphql');
您传递给 readFile
的回调函数异步运行,这意味着 return 从中获取值不会执行任何操作 - readFile
调用的函数是内部已完成执行,并在回调完成时 return 编辑了一个值(空)。
根据经验,在处理 GraphQL 时,您应该远离回调——您的解析器应该始终 return 一个值或一个最终会解析为一个值的 Promise。
幸运的是,fs
有一个异步读取文件的方法,所以你可以这样做:
const root = {
experiment: () => {
const file = fs.readFileSync('./data/experimentExample.json', 'utf8')
return JSON.parse(file)
}
};
// or even cleaner:
const root = {
experiment: () => JSON.parse(fs.readFileSync('./data/experimentExample.json', 'utf8'))
};
再举一个例子,下面是使用 Promise 的方法:
// using Node 8's new promisify for our example
const readFileAsync = require('util').promisify(fs.readFile)
const root = {
experiment: () => readFileAsync('./data/experimentExample.json', {encoding: 'utf8'})
.then(data => JSON.parse(data))
};
// Or with async/await:
const root = {
experiment: async () => JSON.parse(await readFileAsync('./data/experimentExample.json', {encoding: 'utf8'}))
};
当然没有必要对 readFile 进行承诺,因为您已经有了可用的异步方法,但这让您了解了如何使用 Promises,而 GraphQL 很乐意与之合作。