使用 express 和 Mongodb 的 Graphql 查询将无法正常工作?

Posted

技术标签:

【中文标题】使用 express 和 Mongodb 的 Graphql 查询将无法正常工作?【英文标题】:Graphql Query with express and Mongodb won't work properly? 【发布时间】:2020-10-05 19:01:16 【问题描述】:

在我的 express 服务器上使用 graphql 时遇到问题。

重写以更适用

我有一个 mongodb 服务器,其中包含一些示例数据,如下所示,我正在尝试查询我的前端应用程序。

这是我首先尝试做的教程中的数据

db.bios.insertMany([
   
       "_id" : 1,
       "name" : 
           "first" : "John",
           "last" : "Backus"
       ,
       "birth" : ISODate("1924-12-03T05:00:00Z"),
       "death" : ISODate("2007-03-17T04:00:00Z"),
       "contribs" : [
           "Fortran",
           "ALGOL",
           "Backus-Naur Form",
           "FP"
       ],
       "awards" : [
           
               "award" : "W.W. McDowell Award",
               "year" : 1967,
               "by" : "IEEE Computer Society"
           ,
           
               "award" : "National Medal of Science",
               "year" : 1975,
               "by" : "National Science Foundation"
           ,
           
               "award" : "Turing Award",
               "year" : 1977,
               "by" : "ACM"
           ,
           
               "award" : "Draper Prize",
               "year" : 1993,
               "by" : "National Academy of Engineering"
           
       ]
   ,
   
       "_id" : ObjectId("51df07b094c6acd67e492f41"),
       "name" : 
           "first" : "John",
           "last" : "McCarthy"
       ,
       "birth" : ISODate("1927-09-04T04:00:00Z"),
       "death" : ISODate("2011-12-24T05:00:00Z"),
       "contribs" : [
           "Lisp",
           "Artificial Intelligence",
           "ALGOL"
       ],
       "awards" : [
           
               "award" : "Turing Award",
               "year" : 1971,
               "by" : "ACM"
           ,
           
               "award" : "Kyoto Prize",
               "year" : 1988,
               "by" : "Inamori Foundation"
           ,
           
               "award" : "National Medal of Science",
               "year" : 1990,
               "by" : "National Science Foundation"
           
       ]
   
]);

这里有一个非常简单的示例,说明我不想用它来实现正确的输出

const MONGO_URL = 'mongodb://ubika:gdaymerch@localhost:27017/admin';


const mongoCon = () => MongoClient.connect(MONGO_URL)
  .then(client => client.db('bios'));

console.log(mongoCon)

// Construct a schema, using GraphQL schema language
const schema = buildSchema(`
  type Query 
    bios: [Bio]
    bio(id: Int): Bio
  
  type Mutation 
    addBio(input: BioInput) : Bio
  
  input BioInput 
    name: NameInput
    title: String
    birth: String
    death: String
  
  input NameInput 
    first: String
    last: String
  
  type Bio 
    name: Name,
    title: String,
    birth: String,
    death: String,
    awards: [Award]
  
  type Name 
    first: String,
    last: String
  ,
  type Award 
    award: String,
    year: Float,
    by: String
  
`);

// Provide resolver functions for your schema fields
const resolvers = 
  bios: (args, mongoCon) => mongoCon().then(db => db.collection('bios').find().toArray()),
  bio: (args, mongoCon) => mongoCon().then(db => db.collection('bios').findOne( _id: args.id )),
  addBio: (args, mongoCon) => mongoCon().then(db => db.collection('bios').insertOne( name: args.input.name, title: args.input.title, death: args.input.death, birth: args.input.birth)).then(response => response.ops[0])
;

app.use('/graphql', graphqlHTTP(
  context:mongoCon,
  schema,
  rootValue: resolvers,
  graphiql:true

));

以及我与我构建的其余 API 和本教程集成的确切示例。

https://www.digitalocean.com/community/tutorials/how-to-build-and-deploy-a-graphql-server-with-node-js-and-mongodb-on-ubuntu-18-04#step-1-%E2%80%94-setting-up-the-mongodb-database,

//batteries
const express = require("express");
const app = express();


//graphql
const graphqlHTTP = require('express-graphql');
const  buildSchema  = require('graphql');
const  MongoClient  = require('mongodb');

//const admin = require("./utils/admin");
//Security 
const morgan = require("morgan");
const bodyParser = require('body-parser');
const cors = require("cors");

app.use(cors());

//routes

...

//上下文

const MONGO_URL = 'mongodb://ubika:gdaymerch@localhost:27017/admin';

// const mongodb = await MongoClient.connect(MONGO_URL)

// const bios = mongodb.collection('bios')
const context = (client) => MongoClient.connect(MONGO_URL)
  .then(client => client.db('admin')).catch(console);

console.log(context)

// Construct a schema, using GraphQL schema language
const schema = buildSchema(`
  type Query 
    bios: [Bio]
    bio(id: Int): Bio
  
  type Mutation 
    addBio(input: BioInput) : Bio
  
  input BioInput 
    name: NameInput
    title: String
    birth: String
    death: String
  
  input NameInput 
    first: String
    last: String
  
  type Bio 
    name: Name,
    title: String,
    birth: String,
    death: String,
    awards: [Award]
  
  type Name 
    first: String,
    last: String
  ,
  type Award 
    award: String,
    year: Float,
    by: String
  
`);

// Provide resolver functions for your schema fields
const resolvers = 
  bios: (args, context) => context().then(db => db.collection('bios').find().toArray()),
  bio: (args, context) => context().then(db => db.collection('bios').findOne( _id: args.id )),
  addBio: (args, context) => context().then(db => db.collection('bios').insertOne( name: args.input.name, title: args.input.title, death: args.input.death, birth: args.input.birth)).then(response => response.ops[0])
;

app.use('/graphql', graphqlHTTP(
  
  schema,
  rootValue: resolvers,
  graphiql:true
 
));


//Services
const DatabaseService = require('./services/DatabaseService');


DatabaseService.init();


// Provide resolver functions for your schema fields


const resolvers = 
  bios: (args, context) => context().then(db => db.collection('bios').find().toArray())
;



const jwt = require('jsonwebtoken');


function verifyToken(req, res, next) ....



//security

app.use(morgan("dev"));
app.use(bodyParser.urlencoded( extended: false ));

app.use((req, res, next) => 
  //can reaplce * with website we want to allow access
  res.header('Access-Control-Allow-Origin', '*....
);
// routes
...

// get DB entries





//SQL
....


module.exports = app;

现在当我在 graphiQL 中查询这个时,我收到一个错误


  "errors": [
    
      "message": "context is not a function",
      "locations": [
        
          "line": 31,
          "column": 2
        
      ],
      "path": [
        "bio"
      ]
    
  ],
  "data": 
    "bio": null
  

这是查询

bio 
  title
  birth
  death

关于如何解决这个问题的任何想法?我很茫然,很想使用上面留下的列表继续前进

【问题讨论】:

第一个 - 糟糕的教程,滥用上下文 - 上下文是一个对象,而不是 fn - sayasuhendra.github.io/graphql-js/4-connectors .... 第二个使用 graphiql 测试查询 ... 检查网络请求的详细信息以了解正文格式或搜索axios/fetch 使用 graphql 【参考方案1】:

context:作为上下文传递给graphql() 函数的值。 如果未提供上下文,则将请求对象作为上下文传递。

这意味着您可以将任何值传递给上下文。

在本教程中,他提供了一个function,因此在解析器中调用context() 是有意义的。 但是您传递的是object,您需要调整您的代码。试试这个

const mongoCon = () => MongoClient.connect(MONGO_URL).then(client => client.db('bios'));
app.use('/graphql', graphqlHTTP(
    context:  mongoCon ,
    schema,
    rootValue: resolvers,
    ...
));

然后在解析器中

const resolvers = 
    bios: (args, context) => 
        const mongoCon = context.mongoCon;
        mongoCon().then(db => db.collection('bios').find().toArray())
    ,
    ...

//OR by arguments destructuring
const resolvers = 
    bios: (args,  mongoCon ) => mongoCon().then(db => db.collection('bios').find().toArray()),
    ...

【讨论】:

以上是关于使用 express 和 Mongodb 的 Graphql 查询将无法正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Nodejs、Express、Mongoose 和 React 将图像上传到 MongoDB

错误状态:使用 Node.js (express)、Angular 和 MongoDB 的 PUT 请求返回 404

使用 Express、Mongodb 和 EJ 显示下拉动态数据

使用 Express 和 MongoDB - 如何注销用户?

使用node+express+mongodb实现用户注册登录和验证功能

使用 express 和 Mongodb 的 Graphql 查询将无法正常工作?