Запрос Graphql с express и Mongodb не работает должным образом? - PullRequest
2 голосов
/ 16 июня 2020

У меня проблема с использованием graphql на моем express сервере.

переписать, чтобы было более применимо

У меня есть сервер 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-setup-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
}}

Есть идеи, как решить эту проблему? Я в растерянности и с радостью использую список, который я оставил выше

1 Ответ

4 голосов
/ 18 июня 2020

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()),
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...