New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to query for MongoDB ObjectIDs #1518

Closed
alexmcmillan opened this Issue Sep 10, 2018 · 16 comments

Comments

Projects
None yet
8 participants
@alexmcmillan

alexmcmillan commented Sep 10, 2018

I recently updated from 0.13.2 to 14.0.2 which includes breaking changes.

This introduced errors with existing queries which include MongoDB Object Ids (probably from #1382):

ID cannot represent value: { _bsontype: "ObjectID", id: <Buffer 5b 96 3d bf 98 0a 04 09 85 c6 6e a1> }

Repository with complete, minimal repeatable example here:

const Thing = mongoose.model('Thing', new mongoose.Schema({
  id: mongoose.Schema.Types.ObjectId,
  name: String
}));

const ThingType = new GraphQLObjectType({
  name: 'thing',
  fields: function () {
    return {
      id: { type: GraphQLID },
      name: { type: GraphQLString }
    }
  }
});

const RootMutation = new GraphQLObjectType({
  name: 'CreateMutation',
  fields: {
    create: {
      type: ThingType,
      description: 'Create new thing',
      args: {
        name: {
          name: 'Name of Thing',
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: (root, args) => {
        const newThing = new Thing({ name: args.name });
        newThing.id = newThing._id;
        return new Promise((res, rej) => {
          newThing.save(err => {
            if (err) return rej(err);
            res(newThing);
          });
        });
      }
    }
  }
});
@alexmcmillan

This comment has been minimized.

alexmcmillan commented Sep 10, 2018

Background: I'm a learner. Following this tutorial I encountered this problem which was very confusing trying to debug. It would be nice if there was perhaps a clearer error message (*GraphQLID* cannot represent value... (instead of just ID) would have helped me a lot). Perhaps adding an indication of how to properly cast a MongoDB ObjectID?

IvanGoncharov added a commit to APIs-guru/graphql-js that referenced this issue Sep 11, 2018

@IvanGoncharov

This comment has been minimized.

Collaborator

IvanGoncharov commented Sep 11, 2018

@alexmcmillan Thanks for detail description and especially example repo 👍
It should be fixed by #1520


It would be nice if there was perhaps a clearer error message (GraphQLID cannot represent value... (instead of just ID) would have helped me a lot).

Problem is that you can define GraphQL types in SDL without working directly with GraphQL* classes:

type thing {
  id: ID
  name: String
}

So we can't use GraphQLID in error message because it will confuse SDL users.

Perhaps adding an indication of how to properly cast a MongoDB ObjectID?

We can't have mongoose as a dependency so we can't detect that some object is coming from Mongo.

@alexmcmillan

This comment has been minimized.

alexmcmillan commented Sep 12, 2018

@IvanGoncharov that makes perfect sense, thank you for your clear explanations here. Hope your solution gets merged soon so I can come forward to v14 :)

@alexmcmillan alexmcmillan reopened this Sep 12, 2018

IvanGoncharov added a commit to APIs-guru/graphql-js that referenced this issue Sep 14, 2018

IvanGoncharov added a commit to APIs-guru/graphql-js that referenced this issue Sep 18, 2018

@sibelius

This comment has been minimized.

sibelius commented Oct 2, 2018

any changes this gets into 14.0.3?

@RadAcademy

This comment has been minimized.

RadAcademy commented Oct 3, 2018

Yes, I am still stuck using '^0.13.2' as the latest '^14.0.2' continues to give me these issues.

@GlauberF

This comment has been minimized.

GlauberF commented Oct 3, 2018

I would also like to know if it has been fixed for the ^14.0.2,
Why am I having to use the ^0.13.2

I tested the version ^14.0.2 and returned the same problem! :(

@IvanGoncharov

This comment has been minimized.

Collaborator

IvanGoncharov commented Oct 3, 2018

@RadAcademy @GlauberF We plan to include it into the next release.
However since instead of depending on toString we now using toJSON it can't be a patch release. So we are working on 14.1.0 that will include this and a few other features.
We will try to release RC ASAP.

@axe-z

This comment was marked as off-topic.

axe-z commented Oct 11, 2018

I'm a newbie at apollo, me and my aspiration .... arggh. the JS fatigue is real. Wanted to let redux go, by only using this now. here's my very small project:

server:

const express = require("express");
const mongoose = require("mongoose");
require("dotenv").config({ path: "variables.env" }); //a juste besoin du path
//const bodyParser = require('body-parser');
const { ApolloServer, gql} = require('apollo-server-express');
 
const cors = require("cors"); // pour que react chiasse pas en faisant des calls

mongoose
  .connect(process.env.MONGO_URI, { useNewUrlParser: true, useCreateIndex: true })  
  .then(() => console.log("Db connecté"))
  .catch(err => console.error(err));

const app = express();

//Schema
const Blog = require('./models/Blog');
const User = require('./models/User');

// //typedefs et resolvers
const { typeDefs } = require('./schema')
const { resolvers } = require('./resolvers')
 


//pour react
const corsOption = {
  origin: "http://localhost:3000",
   credentials: true
};

app.use(cors(corsOption));


const port =  4444;

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: {
    Blog,
    User
  }
});

server.applyMiddleware({app});


app.listen({ port }, () =>
  console.log(`🚀 Server ready at http://localhost:${port}${server.graphqlPath}`),
);

Blog shema
exports.typeDefs = `

type Blog {
  _id: ID
  title: String!
  author: String
  body: String!
  date: String
}
type Query {
  getAllBlogs: [Blog]
}
type Mutation {
  addBlog(title: String!, author: String, body: String!) : Blog
}
`;

resolver:

exports.resolvers = {
  Query: {
    getAllBlogs: async(root, args, { Blog }) => await Blog.find().sort({
      date: -1  //-1 = desc //1 = ascendant
    })
  },
  Mutation: {
      addBlog: async(root, { title, author, body  }, { Blog }) => {
        const newBlog = await new Blog({
          title, author, body
        }).save()
        return newBlog
      }
  },
 
}

in react WHERE I GET Issues with ID:

import React  from 'react';
import { Query } from "react-apollo";
import gql from "graphql-tag";

const GET_ALL_BLOGS = gql`
  query {
    getAllBlogs {
      !!!!!IF I PUT _ID I GET THE ERROR !!!!!!!!!!!!!
      title
      author
      body
      date
    }
  }
`;

const App = props => {
  return (
      <div>
        <h2>My first Apollo app </h2>
        <Query query={GET_ALL_BLOGS}>
          {({ data : { getAllBlogs } , loading, error }) => {
            if (loading) return "Loading";
            if (error) return `Error!: ${error}`;
            return  (
              <ul>
                {getAllBlogs.map(el =>  <li key={el.WOULDBE_ID}>{el.title}</li>)}
              </ul>
            );
          }}
        </Query>
      </div>
  );
};


index has the client, but it's ok, IT's that simple right now... Not sure what I'm doing wrong

@IvanGoncharov

This comment has been minimized.

Collaborator

IvanGoncharov commented Oct 11, 2018

@axe-z We already have a fix for this issue in #1520
We will try to release it ASAP.

@axe-z

This comment has been minimized.

axe-z commented Oct 11, 2018

oh thanks, when you are at your first steps like me , nosebleeds are ruff.

IvanGoncharov added a commit that referenced this issue Oct 11, 2018

@IvanGoncharov

This comment has been minimized.

Collaborator

IvanGoncharov commented Oct 11, 2018

@alexmcmillan @sibelius @RadAcademy @GlauberF @axe-z I went ahead and merged #1520.
So now you can use our npm branch as a temporary solution until we figure out how to release 14.1.0:
https://github.com/graphql/graphql-js#want-to-ride-the-bleeding-edge

@RadAcademy

This comment was marked as outdated.

RadAcademy commented Oct 13, 2018

Your query needs to match the string type of string! not string

@sachintbits

This comment has been minimized.

sachintbits commented Nov 13, 2018

I had the same issue, i resolved this issue by writing this code in the types definition file of graphql

import mongoose from "mongoose";

const { ObjectId } = mongoose.Types;

ObjectId.prototype.valueOf = function() {
  return this.toString();
};
@sibelius

This comment has been minimized.

sibelius commented Nov 13, 2018

should this be done on mongoose instead of graphql-js?

@vkarpov15 does it make sense to ObjectId implement valueOf?

@vkarpov15

This comment has been minimized.

vkarpov15 commented Dec 4, 2018

@sibelius not a bad idea. Opened up a mongoose issue to track this

@sibelius

This comment has been minimized.

sibelius commented Dec 4, 2018

@vkarpov15 tks, keep the good work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment