Siguiendo este tutorial, tengo un modelo de mangosta: (I ' m usando el término "Cuenta" en lugar de "Todo", pero es lo mismo)

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

Y una GraphQLObjectType:

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

Y una mutación de GraphQL para crear una de estas:

const mutationCreateType = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    add: {
      type: AccountType,
      description: 'Create new account',
      args: {
        name: {
          name: 'Account Name',
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: (root, args) => {
        const newAccount = new Account({
          name: args.name
        });

        newAccount.id = newAccount._id;

        return new Promise((resolve, reject) => {
          newAccount.save(err => {
            if (err) reject(err);
            else resolve(newAccount);
          });
        });
      }
    }
  }
})

Después de ejecutar la consulta:

mutation {
  add(name: "Potato")
  {
    id,
    name
  }
}

En GraphiQL, obtengo la respuesta:

{
  "errors": [
    {
      "message": "ID cannot represent value: { _bsontype: \"ObjectID\", id: <Buffer 5b 94 eb ca e7 4f 2d 06 43 a6 92 20> }",
      "locations": [
        {
          "line": 33,
          "column": 5
        }
      ],
      "path": [
        "add",
        "id"
      ]
    }
  ],
  "data": {
    "add": {
      "id": null,
      "name": "Potato"
    }
  }
}

La creación del objeto fue exitosa, y puedo verla en MongoDB Compass:

From MongoDB Compass showing created object

Pero parece haber un problema al leer el valor.

¿Qué tan compatibles son GraphQLID y mongoose.Schema.Types.ObjectId? Si no son compatibles, ¿estoy malinterpretando el tutorial, particularmente su uso de:

newAccount.id = newAccount._id;

? No puedo decir si GraphQL, o MongoDB, o Mongoose, o algo completamente distinto, está arrojando el error.

EDITAR

Cualquier información sobre el error

El ID no puede representar el valor: {_bsontype: \ "ObjectID \", id:}

Sería muy útil. Siento que me dice que no puede serializar un objeto BSON ... pero luego lo muestra serializado. Incluso saber qué tecnología (mongo? Mongoose? Graphql?) Estaba generando el error ayudaría. No estoy teniendo suerte con Google.

EDITAR 2

Esto fue causado por un cambio al paquete graphql introducido recientemente, y allí es un PR en espera de fusión que lo resuelve.

3
Alex McMillan 9 sep. 2018 a las 13:06

3 respuestas

La mejor respuesta

No encontré un problema y ejecuté este código con una de mis bases de código existentes. Excepto que envolví la mutación en GraphQLObjectType.

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {
        addAccount: {
            type: AccountType,
            description: 'Create new account',
            args: {
                name: {
                    name: 'Account Name',
                    type: new GraphQLNonNull(GraphQLString)
                }
            },
            resolve: (root, args) => {
                const newAccount = new Account({
                    name: args.name
                });

                newAccount.id = newAccount._id;

                return new Promise((resolve, reject) => {
                    newAccount.save(err => {
                        if (err) reject(err);
                        else resolve(newAccount);
                    });
                });
            }
        }
    });

Para obtener el ejemplo de trabajo: Clone el repositorio. En este repositorio, la aplicación usa v0.13.2 y usted está usando v14.0.2 instalado a través de npm i graphql. Degradar graphql a v0.13.2.

2
Shivam Pandey 10 sep. 2018 a las 09:33

Entonces, lo que acabo de encontrar es que _id es del tipo ObjectID pero parece estar implícitamente en String. Entonces, si define su tipo de identificación de modelo de mangosta como String en lugar de mongoose.Schema.Types.ObjectId, entonces debería funcionar. Usando su código actual (del tutorial de compose.com) que copia _id al id, el resultado será que, en Mongo (después de guardar), el _id será del tipo ObjectID y su identificación del modelo será del tipo cuerda.

En otras palabras, en lugar de esto

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

Haga esto

const Account = mongoose.model('Account', new mongoose.Schema({
  id: String,
  name: String
}));
1
Sinaesthetic 21 sep. 2018 a las 23:52

¡Usé ID y funciona bien! ¡La causa de su problema no es el tipo de identificación! es porque lo proporcionas con un valor incorrecto: ObjectID('actuall id')

Para solucionar este problema, llame a la función toJson para cada dato extraído, o simplemente agregue un id virtual como este:

YourSchema.virtual('id').get(function() {
    return this.toJSON()._id
}
2
Mohsen ZareZardeyni 9 sep. 2018 a las 12:59