graphql-compose-mongoose generating an error: Expected [object Object] to be a GraphQL schema - graphql-js

I'm new to graphql-compose
I'm trying to launch a first service on a simple mongoose schema:
graphql.js :
import mongoose from 'mongoose'
import { composeWithMongoose} from 'graphql-compose-mongoose'
import { schemaComposer } from 'graphql-compose'
const db = require( '../models/db' )
//const mongoose = require('mongoose');
const folderDAO = mongoose.model('folder');
const customizationOptions = {}; // left it empty for simplicity, described below
const folderTC = composeWithMongoose(folderDAO, customizationOptions);
schemaComposer.rootQuery().addFields({
folderOne: folderTC.getResolver('findOne'),
})
const graphqlSchema = schemaComposer.buildSchema()
console.log("Schema built : ", graphqlSchema )
export default graphqlSchema
Now in my server code, I have this:
const express = require('express');
const graphqlHTTP = require('express-graphql')
const GraphQLSchema = require('./app_api/routes/graphql')
app.use('/graphql', graphqlHTTP({
schema: GraphQLSchema,
graphiql: true,
formatError: error => ({
message: error.message,
locations: error.locations,
stack: error.stack ? error.stack.split('\n') : [],
path: error.path
})
}));
On graphiql, when I attempt the following query:
{
folderOne(filter: {}, sort: _ID_ASC) {
name
}
}
I get the following error:
{
"errors": [
{
"message": "Expected [object Object] to be a GraphQL schema.",
"stack": [
"Error: Expected [object Object] to be a GraphQL schema.",
" at invariant (/Users/zied/work/share_place/node_modules/graphql/jsutils/invariant.js:19:11)",
" at validateSchema (/Users/zied/work/share_place/node_modules/graphql/type/validate.js:55:60)",
" at assertValidSchema (/Users/zied/work/share_place/node_modules/graphql/type/validate.js:80:16)",
" at validate (/Users/zied/work/share_place/node_modules/graphql/validation/validate.js:58:35)",
" at /Users/zied/work/share_place/node_modules/express-graphql/dist/index.js:139:52",
" at <anonymous>",
" at process._tickDomainCallback (internal/process/next_tick.js:228:7)"
]
}
]
}
What could I be missing???
p.s: sorry I attempted to tag the question with graphql-compose-mongoose but the tag doesn't exist, so I tagged it with graphql-js

Actually the issue was here:
const GraphQLSchema = require('./app_api/routes/graphql')
has to be replaced with
const GraphQLSchema = require('./app_api/routes/graphql').default
since we exported it as default
More info can be found here: https://github.com/graphql-compose/graphql-compose-mongoose/issues/103

Related

Error serializing `.meetups[0].title` returned from `getStaticProps` in "/" ` [duplicate]

This question already has answers here:
Error serializing `.remarkBody` returned from `getStaticProps` . Reason: `undefined` cannot be serialized as JSON
(2 answers)
Closed 11 months ago.
I'm using next js with MongoDB, I'm getting the error serializing when submitting the form
error
Server Error
Error: Error serializing .meetups[0].title returned from getStaticProps in "/".
Reason: undefined cannot be serialized as JSON. Please use null or omit this value.
function HomePage(props){
return <MeetupList meetup={props.meetups} ></MeetupList>
}
export async function getStaticProps(){
const client = await MongoClient.connect("mongodb+srv://User:Password#cluster0.random.mongodb.net/meetups?retryWrites=true&w=majority");
const db = client.db();
const meetupsCollection = db.collection("meetups");
const meetups = await meetupsCollection.find().toArray();
client.close();
return {
props: {
meetups : meetups.map(meetup =>( {
title: meetup.title ,
address: meetup.address ,
source: meetup.source ,
id : meetup._id.toString()
}))
},
revalidate: 1
};
}
export default HomePage;
you should wrap the meetups prop value with JSON.stringify, see below:
return {
props: {
meetups: JSON.parse(
JSON.stringify(
meetups.map((meetup) => ({
title: meetup.title,
address: meetup.address,
source: meetup.source,
id: meetup._id.toString(),
}))
)
),
},
revalidate: 1,
};

MongoServerError: BSON field 'update.apiVersion' is an unknown field

Here I am using the official mongodb driver btw.
const { MongoClient, ServerApiVersion } = require('mongodb');
const CLient = new MongoClient(process.env.uri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1});
const db = CLient.db("Discord").collection("Discord");
CLient.connect(err => {
//const db = CLient.db("Discord").collection("Discord");
console.log("Connected to the Database")
//CLient.close();
const prefix = await db.find({guildid: msg.guild.id});
await db.updateOne({guildid: msg.guild.id}, {$set: {prefix: newPrefix}});
if (!prefix) {
let prefix = db.insertOne({guildid: msg.guild.id, prefix: newPrefix})
return msg.channel.send(`Your server prefix is now ${newPrefix}`);
}
return msg.channel.send(`Your server prefix is now ${newPrefix}`);
});
msg is already defined here as a object btw and newPrefix is also defined. So the database connected successfully according to the logs. The error is thrown when the code is run
MongoServerError: BSON field 'update.apiVersion' is an unknown field this is the error msg. How can i fix this
I had the same problem. This is related to how you instantiate the client - i.e., this won't fail:
const Client = new MongoClient(process.env.uri);

ArangoDB Joi Foxx mapping to Swagger is incorrect

I define a bean called TestBean on joi syntax. Then defined another bean BeanMethodDocument which uses TestBean schema/bean. Generated Swagger/model ignores this argument, yet an array defined with TestBean works?
The following JOI syntax seems to lose the TestBean definition: "arg: joi.object().schema(TestBean).required(),"
'use strict';
var createRouter = require('#arangodb/foxx/router');
var joi = require('joi');
var router = createRouter();
module.context.use(router);
const TestBean = joi.object().required().keys({
member1: joi.array().items(joi.string().required()),
member2: joi.number().required()
});
const BeanMethodDocument = joi.object().required().keys({
arg: joi.object().schema(TestBean).required(),
argArray: joi.array().items(TestBean).required(),
option: joi.string().valid('Empty','Full','HalfFull','HalfEmpty')
});
router.post('/beanMethod', function (req, res) {
const arg = req.body.arg;
const argArray = req.body.argArray;
const option = req.body.option;
res.send({result:true});
})
.body(BeanMethodDocument, 'beanMethod POST request')
.response(joi.boolean().required(), 'beanMethod POST response')
.summary('beanMethod summary')
.description('beanMethod description');
Generated Swagger document shows the arg argument as empty?
"arg": {
"type": "object",
"properties": {},
"additionalProperties": false
},
According to the JOI documentation (https://github.com/hapijs/joi/blob/v15.1.0/API.md#objectschema)
The schema function you used there does return the schema of the current object, it does not set it. You can instead of the joi.object() simply use the TestBean like this:
const BeanMethodDocument = joi.object().required().keys({
arg: TestBean.required(),
argArray: joi.array().items(TestBean).required(),
option: joi.string().valid('Empty','Full','HalfFull','HalfEmpty')
});
in my local tests this work end you end up with:
{
"arg": {
"member1": [
"string"
],
"member2": 0
},
"argArray": [
{
"member1": [
"string"
],
"member2": 0
}
],
"option": "Empty"
}

How to validate for ObjectID

Using Joi schema validation, is it possible to validate against MongoDB ObjectID's?
Something like this could be great:
_id: Joi.ObjectId().required().error(errorParser),
const Joi = require('#hapi/joi')
Joi.objectId = require('joi-objectid')(Joi)
const schema = Joi.object({
id: Joi.objectId(),
name: Joi.string().max(100),
date: Joi.date()
})
checkout https://www.npmjs.com/package/joi-objectid
I find that if I do
Joi.object({
id: Joi.string().hex().length(24)
})
it works without installing any external library or using RegEx
The hex makes sure the string contains only hexadecimal characters and the length makes sure that it is a string of exactly 24 characters
This package works if you are using the new version of Joi.
const Joi = require('joi-oid')
const schema = Joi.object({
id: Joi.objectId(),
name: Joi.string(),
age: Joi.number().min(18),
})
package: https://www.npmjs.com/package/joi-oid
If you want a TypeScript version of the above library integrated with Express without installing anything:
import Joi from '#hapi/joi';
import { createValidator } from 'express-joi-validation';
export const JoiObjectId = (message = 'valid id') => Joi.string().regex(/^[0-9a-fA-F]{24}$/, message)
const validator = createValidator({
passError: true,
});
const params = Joi.object({
id: JoiObjectId().required(),
});
router.get<{ id: string }>(
'/:id',
validator.params(params),
(req, res, next) => {
const { id } = req.params; // id has string type
....
}
);
I share mine
let id =
Joi.string()
.regex(/^[0-9a-fA-F]{24}$/)
.message('must be an oid')
With joi naked package you can use this:
const ObjectId = joi.object({
id: joi.binary().length(12),
})
This is a core function without any external package. I have used Joi and mongoose packages to achieve it.
const Joi = require("joi");
const ObjectID = require("mongodb").ObjectID;
const schema = Joi.object({
id: Joi.string().custom((value, helpers) => {
const filtered = ObjectID.isValid(value)
return !filtered ? helpers.error("any.invalid") : value;
},
"invalid objectId", ).required(),
name: Joi.string(),
age: Joi.number().min(18),
})
I see many correct answers here, but I also want to express my opinion.
I am not against installing npm packages, but installing one package just to validate an object id is overkill. I know programmers are lazy but C'mooon :)
Here is my full code function that validates two object id properties, very simple:
function validateRental(rental) {
const schema = Joi.object({
movieId: Joi.string()
.required()
.regex(/^[0-9a-fA-F]{24}$/, 'object Id'),
customerId: Joi.string()
.required()
.regex(/^[0-9a-fA-F]{24}$/, 'object Id'),
})
const { error } = schema.validate(rental)
return {
valid: error == null,
message: error ? error.details[0].message : null,
}
}
This way, if any of the properties contain invalid id like this:
{
"movieId": "123456",
"customerId": "63edf556f383d108d54a68a0"
}
This will be the error message:
`"movieId" with value "123456" fails to match the object Id pattern`

unexpected token while runing gaphql server

i runing my graphql server via terminal,, but when i am runing
$node server
geeting error like this
/home/bimoan/Desktop/bibitnomic-api/server.js:3
var { buildSchema } = require("graphql");
^
SyntaxError: Unexpected token {
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:374:25)
at Object.Module._extensions..js (module.js:417:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Function.Module.runMain (module.js:442:10)
at startup (node.js:136:18)
at node.js:966:3
this is my server.js
var express = require("express");
var express_graphql = require("express-graphql");
var { buildSchema } = require("graphql");
// GraphQL schema
var schema = buildSchema(`
type Query {
message: String,
User: String
}
`);
// Root resolver
var root = {
message: () => "Hello World!",
User: () => " Bimo ANugrah"
};
// Create an express server and a GraphQL endpoint
var app = express();
app.use(
"/graphql",
express_graphql({
schema: schema,
rootValue: root,
graphiql: true
})
);
app.listen(4000, () =>
console.log("Express GraphQL Server Now Running On localhost:4000/graphql")
);
where my code is wrong ??
I was not change anything what and why this can happen? Can anyone help me?