简体   繁体   中英

Graphql Query with express and Mongodb won't work properly?

I'm having an issue with using graphql on my express server.

re-write to be more applicable

I have a mongodb server with some example data in it as below I am trying to query for my front end application.

This is the data from the tutorial that I am trying to do first

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"
           }
       ]
   }
]);

A very simple example of what I'mt trying to use to achieve a proper output is here

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

}));

And the exact example of my integration with the rest of the API i've built and this tutorial here.

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

...

//context

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;

Now when i query this inside the graphiQL I receive an error of

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

This being the query

{bio {
  title
  birth
  death
}}

Any ideas on how to solve this issue? I am at a loss and would love to get flying ahead with using the list I've left above

context : A value to pass as the context to the graphql() function. If context is not provided, the request object is passed as the context.

This means you can passe any value to context.

In this tutorial he provided a function , so it make sens to call context() in the resolvers. But you are passing an object , you need to adapt your code. Try this

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

Then in the 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()),
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM