GraphQL:从 JSON 文件源完成查询

Posted

技术标签:

【中文标题】GraphQL:从 JSON 文件源完成查询【英文标题】:GraphQL: fulfill query from JSON file source 【发布时间】:2018-02-18 14:04:45 【问题描述】:

我刚刚开始使用 GraphQL,我想要一个使用磁盘上的 JSON 文件作为数据源的解析器。到目前为止我得到的结果导致 GraphQL 返回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'); 

【问题讨论】:

【参考方案1】:

您传递给readFile 的回调函数异步运行,这意味着从它返回一个值不会做任何事情——readFile 调用内部的函数已完成执行并返回一个值(null ) 到您的回调完成时。

根据经验,在处理 GraphQL 时,您应该远离回调——您的解析器应该始终返回一个值或最终将解析为一个值的 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 查询中的多个源 (Gatsby)

angular, apollo-client, graphQL - 从 graphql 查询中选择所有字段

Gatsby:在页面上组合两个 graphql 源(.json 和 .jpg 源)

如何从 MySQL 查询中将 json 返回到 GraphQL?

GraphQL从axios返回空数据[重复]

如何从 GraphQL 获取 json