Я разработчик внешнего интерфейса, пытающийся расширить свой кругозор в новом проекте Next, изучая Node, Mon go и серверную часть GraphQL впервые. Apollo показался мне самым простым способом освоиться, поскольку я уже использовал клиентский Apollo в предыдущих проектах.
Я следовал официальным документам , где я узнал о apollo-datasource-mongodb (казалось бы, лучший способ подключить мой сервер Apollo прямо к локальной базе данных Mon go. К сожалению, для меня нет примеров репозиториев этого пакета в действии, чтобы я мог обмануть, так что меня оставили в тупике.
У меня mon go, работающий локально через mongod
, и я могу выполнять успешные find()
запросы через оболочку mon go, поэтому я знаю, что сама база данных находится в хорошем состоянии и содержит почти 600 000 записей (я работаю с довольно большим набором данных).
У меня также есть доступ к игровой площадке Apollo на localhost:4000
, поэтому Я знаю, что сервер правильно запускается и подключается к базе данных (с соответствующими советами / ошибками схемы, которые мне с тех пор удалось устранить).
Вот запрос, который я использую на игровой площадке:
{
item(id: 22298006) {
title
}
}
и вот что я получаю в ответ:
{
"errors": [
{
"message": "Topology is closed, please connect",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"item"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"name": "MongoError",
"stacktrace": [
"MongoError: Topology is closed, please connect",
...
]
}
}
}
],
"data": {
"item": null
}
}
Я прикрепил файл моего сервера ниже. У меня есть подозрение, что это может быть какая-то ошибка тайм-аута, например, требуется много времени, чтобы прочесать все записи 600 КБ, чтобы найти ту, с указанным мной идентификатором? Когда я удаляю useUnifiedTopology: true
из определения MongoClient, я получаю другую ошибку:
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
, но я не использую asyn c или обещания сам. Что заставляет меня задуматься - я должен быть? Могу ли я как-то задержать процесс, пока я жду возврата из findOneById()
(если это действительно проблема)?
В качестве отдельного случая я видел по крайней мере одну примерную базу кода, в которую был включен MongoClient внутри себя объявление Сервера (также из пакета 'mongodb'
npm). Может ли реализация чего-то подобного избавить меня от необходимости блокировать окно терминала с помощью mongod
каждый раз, когда я хочу работать над моим проектом?
Большое спасибо за ваше время! Если я смогу заставить это работать, я обязательно сделаю полную запись на Medium или что-то подобное, чтобы проложить путь для других, желающих соединить MongoClient с ApolloServer для быстрого и простого API.
index. js
const { MongoClient } = require('mongodb');
const assert = require('assert');
const { ApolloServer, gql } = require('apollo-server');
const { MongoDataSource } = require('apollo-datasource-mongodb');
const client = new MongoClient('mongodb://localhost:27017/projectdb', { useNewUrlParser: true, useUnifiedTopology: true }, (err) => {
err && console.log(err);
});
client.connect((err) => {
assert.equal(null, err);
client.close();
});
const db = client.db();
class Items extends MongoDataSource {
getItem(id) {
return this.findOneById(id);
}
}
const typeDefs = gql`
type Item {
id: Int!
title: String!
}
type Query {
item(id: Int!): Item
}
`;
const resolvers = {
Query: {
item: (_, { id }, { dataSources }) => dataSources.items.getItem(id),
}
}
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => ({
items: new Items(db.collection('items')),
}),
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${ url }`);
});