Home  >  Article  >  Backend Development  >  Reuse models and remove fields from responses in Fiber/MongoDB

Reuse models and remove fields from responses in Fiber/MongoDB

WBOY
WBOYforward
2024-02-08 21:27:181114browse

重用模型并从 Fiber/MongoDB 的响应中删除字段

In this article, php editor Zimo will introduce how to delete fields and reuse models in Fiber/MongoDB responses. When we get data from the database, sometimes we need to delete some fields to meet specific needs or to protect sensitive information. Fiber/MongoDB is a popular PHP framework that allows you to quickly build high-performance web applications. In this article, we will learn how to improve the reusability and maintainability of your code by using the power of Fiber/MongoDB to remove fields and reuse models in your application.

Question content

I'm trying not to create code walls and not redeclare code when it's not needed.

My two main questions now are:

In line 47, the existing user model userCollection.FindOne(ctx, filter, opts).Decode(&user) is overwritten/decoded, but it is not updated, line 46 The options in are not applied unless I declare var user2 = models.User and decode to user2 on line 47, then return user2

on line 49

Line 46 has opts := options.FindOne().SetProjection(bson.M{"password": 0}). If I use the second user user2 from the example above, it returns the password in the JSON response but it is empty. Is it possible to completely remove the password key from the response without creating another user model just to use it in the response?

func CreateUser(c *fiber.Ctx) error {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    var user models.User
 
    //validate the request body
    if err := c.BodyParser(&user); err != nil {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": err.Error()}})
    }
 
    //use the validator library to validate required fields
    if validationErr := validate.Struct(&user); validationErr != nil {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": validationErr.Error()}})
    }
    var email = &user.Email
 
    count, err := userCollection.CountDocuments(ctx, bson.M{"email": email})
    if err != nil {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": "Something went wrong"}})
    }
    if count > 0 {
        return c.Status(http.StatusBadRequest).JSON(responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &fiber.Map{"data": "Email already in use"}})
    }
 
    //set the status, hash password, set activate token and updated at
    status := 0
    password := hashPassword(*user.Password)
    activateToken := uuid.New().String()
    updatedAt, _ := time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))
 
    //create user object
    user.ID = primitive.NewObjectID()
    user.Password = &password
    user.Status = &status
    user.ResetToken = &activateToken
    user.CreatedAt = updatedAt
    user.UpdatedAt = updatedAt
 
    result, err := userCollection.InsertOne(ctx, user)
    if err != nil {
        return c.Status(http.StatusInternalServerError).JSON(responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &fiber.Map{"data": err.Error()}})
    }
 
    //get created user from the DB and cast it into UserResponse model
    filter := bson.M{"_id": result.InsertedID}
    opts := options.FindOne().SetProjection(bson.M{"password": 0})
    userCollection.FindOne(ctx, filter, opts).Decode(&user)
    //return created user
    return c.Status(http.StatusOK).JSON(responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &fiber.Map{"data": user}})
}

I have tried creating a separate model UserResponse without the password field and declaring the second User model in the CreateUser function to be able to view the output of FindOne with the options in the response.

Solution

After a few hours of figuring it out and posting it here, I had a brilliant moment.

All the changes made here is to redeclare the user as an empty user model:

    user = models.User{} // <- the fix
    filter := bson.M{"_id": result.InsertedID}
    opts := options.FindOne().SetProjection(bson.M{"password": 0})
    userCollection.FindOne(ctx, filter, opts).Decode(&user)

The above is the detailed content of Reuse models and remove fields from responses in Fiber/MongoDB. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete