Après avoir utilisé InsertOne
pour créer un nouveau document, lorsque je renvoie le résultat, j'obtiens un tableau de nombres plutôt qu'un ObjectID
. Dans la base de données, l'ID génère correctement.
type User struct {
ID string
Email string
Username string
Password string
}
var db = ...
// UserStore creates user
func UserStore(c echo.Context) (err error) {
coll := db.Collection("users")
u := new(User)
if err = c.Bind(u); err != nil {
return c.JSON(http.StatusInternalServerError, err)
}
result, err := coll.InsertOne(
context.Background(),
bson.NewDocument(
bson.EC.String("email", u.Email),
bson.EC.String("username", u.Username),
bson.EC.String("password", u.Password),
),
)
if err != nil {
return c.JSON(http.StatusInternalServerError, err)
}
return c.JSON(http.StatusCreated, result)
}
Cela renvoie quelque chose comme InsertedID: [90, 217, 85, 109, 184, 249, 162, 204, 249, 103, 214, 121]
au lieu d'un ObjectID
normal. Comment puis-je retourner le ObjectID
réel du document nouvellement inséré?
Un Collection.InsertOne()
réussi renvoie un résultat de type mongo.InsertOneResult
, qui est une structure enveloppant l'ID du document nouvellement inséré:
type InsertOneResult struct {
// The identifier that was inserted.
InsertedID interface{}
}
Le pilote officiel de MongoDB Go utilise le primitive.ObjectID
type pour représenter les ObjectIds MongoDB. Ce type est un tableau d'octets simple:
type ObjectID [12]byte
Pour accéder à ce type, vous devez importer le package primitif .
import "go.mongodb.org/mongo-driver/bson/primitive"
InsertOneResult.InsertedID
contiendra un type dynamique de primitive.ObjectID
. Le primitive.ObjectID
type ne définit pas de méthode de marshaling JSON personnalisée (n'implémente pas json.Marshaler
), ce qui signifie que lorsque le résultat est converti en JSON, les règles de marshaling par défaut seront utilisées, ce qui pour un tableau d'octets (pas de tranche) est ce que vous voyez: la représentation décimale des octets de l'ObjectID.
Vous ne devez pas convertir une valeur de type InsertOneResult
en JSON, car elle (ou plutôt primitive.ObjectID
lui-même) n'est pas "compatible JSON" (du moins pas dans la version actuelle).
Au lieu de cela, créez/encapsulez votre propre type où vous définissez à quoi vous voulez que le résultat ressemble en JSON, par exemple:
if oid, ok := result.InsertedID.(primitive.ObjectID); ok {
return c.JSON(http.StatusCreated, map[string]interface{}{
"id": oid.String(),
})
} else {
// Not objectid.ObjectID, do what you want
}
Le code ci-dessus entraînerait une réponse JSON comme celle-ci:
{"id":"ObjectID(\"5ad9a913478c26d220afb681\")"}
Ou si vous voulez juste la représentation hexadécimale:
if oid, ok := result.InsertedID.(primitive.ObjectID); ok {
return c.JSON(http.StatusCreated, map[string]interface{}{
"id": oid.Hex(),
})
}
Ce qui serait:
{"id":"5ad9a913478c26d220afb681"}