问题
I am new to Golang and Graphql so I probably messed a lot of the configuration up but I am struggling to get values returned from my database using the GraphQL API I created. Whenever I query my database using the GraphQL API I created in Golang It throws the error cannot decode UTC datetime into a string type and struggles to get the id out.
Here is my GrapqhQL schema:
type User {
_id: ID!
username: String!
passwordHash: String!
email: String!
userInfo: userStats
profileStats: profileInfo
}
type userStats {
firstName: String
lastName: String
birthday: String
dateCreated: String!
nativeLanguage: String
currentlyLearning: String
location: Location
}
type Location {
city: String
state: String
zipcode: Int
country: String
}
type profileInfo {
level: Int
xp: Int
xpTillNextLevel: Int
posts: Int
}
input NewUser {
id: ID!
username: String!
passwordHash: String!
email: String!
userStats: String
profileInfo: String
}
type Mutation {
createUser(input: NewUser!): User!
}
type Query {
users: [User!]!
user(id: ID!): User!
}
Here is my code that executes when a query is provided:
func (u *UserRepo) GetUsers() ([]*model.User, error) {
var users []*model.User
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
usersCollection := u.DB.Collection(u.KEYS["collection"].(string))
cursor, err := usersCollection.Find(ctx, bson.M{})
if err != nil {
fmt.Println(err)
return nil, err
}
if err = cursor.All(ctx, &users); err != nil {
fmt.Println(err)
return nil, err
}
fmt.Println(users[0])
return users, nil
}
func (u *UserRepo) GetUserById(id string) (*model.User, error) {
var user model.User
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
usersCollection := u.DB.Collection(u.KEYS["collection"].(string))
userID, err := primitive.ObjectIDFromHex(id)
if err != nil {
fmt.Println("Invalid ObjectID")
}
err = usersCollection.FindOne(ctx, bson.M{"_id": userID}).Decode(&user)
if err != nil {
fmt.Println("error retrieving user userid : " + id)
fmt.Printf("error: %d", err)
//return nil, err
}
fmt.Println(err)
fmt.Println(user)
return &user, nil
}
If I uncomment the return nil,err on the bottom query for selecting one user by the id, it will just return the error of the date and no information so I am leaving it commented out for testing purposes.
my query and result
query:
query getUsers {
user(id: "5ea75c4c67f9266c89dfb659") {
_id
username
email
passwordHash
userInfo{
lastName
dateCreated
location{
state
}
}
profileStats{
level
}
}
}
result:
{
"data": {
"user": {
"_id": "",
"username": "Aerith",
"email": "Aerith@LanguageLearning.com",
"passwordHash": "testingpassword",
"userInfo": {
"lastName": "Gainsborough",
"dateCreated": "",
"location": null
},
"profileStats": null
}
}
}
and here is example dataset that I made for testing in my MongoDB database
db.users.findOne({_id: ObjectId("5ea75c4c67f9266c89dfb659")})
{
"_id" : ObjectId("5ea75c4c67f9266c89dfb659"),
"username" : "Aerith",
"passwordHash" : "testingpassword",
"email" : "Aerith@LanguageLearning.com",
"userInfo" : {
"firstName" : "Aerith",
"lastName" : "Gainsborough",
"birthday" : ISODate("1985-02-07T00:00:00Z"),
"dateCreated" : ISODate("2020-04-27T22:27:24.650Z"),
"nativeLanguage" : "English",
"currentlyLearning" : "Japanese",
"location" : {
"city" : "Sector 5",
"state" : "Midgar",
"zipcode" : 77777,
"country" : "FF7"
}
},
"profileStats" : {
"level" : 1,
"xp" : 0,
"xpTillNextLevel" : 1000,
"comments" : 0,
"posts" : 0
}
}
Also the location and profile stats are just coming back empty and null and I have no clue why. Sorry for the long amount of code but I am trying to provide the most information possible to assist with finding the answer. Hopefully, this helps and I can get some assurance on how to fix this issue. Thank you for all your help in advance.
edit: after some testing in the userStats type I can get the firstName and lastName but it fails and the cursor crashes because of the data error when it hits birthday. This is why everything is null under birthday. So the issues is how do I decode the mongo date so I can put in the userStates. I am tempted to just pull everything as bson and convert it to correct model structs but that seems like to much extra work and I really do not want to resort to this.
回答1:
Some BSON types doesn't have direct mapping with Go primitive types, so you need types with custom unmarshalling, either your own made or already done on bson/primitive package
Try defining your user stats struct that way:
import "go.mongodb.org/mongo-driver/mongo/primitive"
type UserStats {
...
BirthDay primitive.DateTime `bson:"birthday"`
//OR BirthDay primitive.Timestamp `bson:"birthday"`
...
}
https://pkg.go.dev/go.mongodb.org/mongo-driver/bson@v1.3.3?tab=doc#hdr-Native_Go_Types
https://pkg.go.dev/go.mongodb.org/mongo-driver/bson/primitive
https://pkg.go.dev/go.mongodb.org/mongo-driver/bson/primitive?tab=doc#DateTime
https://pkg.go.dev/go.mongodb.org/mongo-driver/bson/primitive?tab=doc#Timestamp
来源:https://stackoverflow.com/questions/61511365/golang-graphql-mongodb-struggling-to-get-date-and-id-out-of-the-database