graphql-js: Unable to query for MongoDB ObjectIDs

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

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 7
  • Comments: 23 (4 by maintainers)

Commits related to this issue

Most upvoted comments

@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

@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.

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();
};

@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.

I’ve made a field resolver to help on this

import { GraphQLNonNull, GraphQLString } from 'graphql';
import { Types } from 'mongoose';

export const mongooseIDResolver = {
  _id: {
    type: GraphQLNonNull(GraphQLString),
    description: 'mongoose _id',
    resolve: ({ _id }: { _id: Types.ObjectId}) => ({ _id: _id.toString() }),
  },
};

so if you want to expose an _id in your GraphQL, you need a custom type or transform ObjectId to string

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

any changes this gets into 14.0.3?