使用 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 - 如何注销用户?