webentwicklung-frage-antwort-db.com.de

Welcher Typ ist der richtige Typ für ein ObjectId-Feld in mongoose und GraphQL?

Nach diesem Tutorial habe ich ein Mungo-Modell: (Ich verwende den Begriff "Account" anstelle von "Todo", aber es ist dasselbe).

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

und ein GraphQLObjectType:

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

und eine GraphQL-Mutation, um eine davon zu erstellen:

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

Nach dem Ausführen der Abfrage:

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

in GraphiQL bekomme ich die Antwort:

{
  "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"
    }
  }
}

Die Erstellung des Objekts war erfolgreich und ich kann es in MongoDB Compass sehen:

 From MongoDB Compass showing created object

es scheint jedoch ein Problem beim Lesen des Wertes zu geben.

Wie kompatibel sind GraphQLID und mongoose.Schema.Types.ObjectId? Wenn sie nicht kompatibel sind, missverstehe ich das Tutorial, insbesondere die Verwendung von:

newAccount.id = newAccount._id;

? Ich kann nicht sagen, ob der Fehler von GraphQL, MongoDB, Mongoose oder etwas anderem ausgelöst wurde.

EDIT

Alle Informationen zum Fehler

Die ID kann keinen Wert darstellen: {_bontype:\"ObjectID \", id:}

wäre sehr hilfreich. Ich habe das Gefühl, dass es mir sagt, dass es kein BSON-Objekt serialisieren konnte, aber dann wird es serialisiert angezeigt. Sogar zu wissen, welche Tech (Mongo? Mongoose? Graphql?) Den Fehler erzeugte, würde helfen. Ich habe kein Glück mit Google.

EDIT 2

Dies wurde verursacht durch eine Änderung des kürzlich eingeführten graphql-Pakets, und es gibt eine PR / erwarte eine Fusion, die es auflöst.

3
Alex McMillan

Ich habe kein Problem gefunden und diesen Code mit einer meiner vorhandenen Codebasis ausgeführt. Außer dass ich die Mutation in GraphQLObjectType eingepackt habe.

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

Um das Arbeitsbeispiel zu erhalten: Clone Repo. In diesem Repo verwendet die App v0.13.2 und Sie verwenden v14.0.2, die über npm i graphql installiert ist. Downgrade von graphql auf v0.13.2.

3
Shivam Pandey

Ich habe ID verwendet und es funktioniert gut! Ursache Ihres Problems ist nicht der Typ der ID! Es ist nur so, dass Sie es mit einem falschen Wert angeben: ObjectID('actuall id')

Um dieses Problem zu beheben, rufen Sie die Funktion toJson für jede abgerufene Daten auf oder fügen Sie einfach eine virtuelle id wie folgt hinzu:

YourSchema.virtual('id').get(function() {
    return this.toJSON()._id
}
1

Ich habe gerade festgestellt, dass _id vom Typ ObjectID ist, aber implizit in String umgewandelt wird. Wenn Sie also Ihren Moose-Model-ID-Typ als String anstelle von mongoose.Schema.Types.ObjectId definieren, sollte dies funktionieren. Wenn Sie Ihren aktuellen Code (aus dem Tutorial compose.com) verwenden, der _id in die ID kopiert, führt dies dazu, dass in Mongo (nach dem Speichern) die _id vom Typ ObjectID und Ihre Modell-ID den Typ string haben.

Mit anderen Worten, stattdessen

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

Mach das

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