php Editor Xigua will take you through this article to learn how to use Postgres and MongoDB for CRUD operations. Postgres is a relational database, while MongoDB is a document database. CRUD operations refer to the process of creating (Create), reading (Read), updating (Update) and deleting (Delete) data. By combining these two different types of databases, you can choose the most suitable database for data operations based on different needs to improve efficiency and flexibility. Next, let us explore the application of these two databases in CRUD operations!
I am fairly new to Go and backends, and am participating in the Go internship program. We built a CRUD that connects to a psql database and now I'm told to connect to mongoDB, which we will use for development and PSQL will be used for production. Do I have to create a new handler for mongo from scratch or can I use the same handler and somehow determine the type of database being used and use the logic accordingly? For example, I have a handler for the user registration endpoint:
func (ctrl *UserController) Register(c *gin.Context) { var user models.User if err := c.BindJSON(&user); err != nil { c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{ "error": true, "message": err.Error(), }) return } err := ctrl.userService.Register(&user) if err != nil { c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{ "error": true, "message": err.Error(), }) return } c.JSON(http.StatusCreated, gin.H{ "message": "successfully created an user", }) } func (svc *UserService) Register(user *models.User) error { if svc.userRepo.CheckIfEmailExists(user.Email) { return errors.New("user already registered") } hash, err := svc.generatePasswordHash(user.Password) if err != nil { return errors.New("err can't register user") } user.Password = hash return svc.userRepo.Insert(user) } func (repo *UserRepository) CheckIfEmailExists(mail string) bool { var user models.User err := repo.dbClient.Debug().Model(models.User{}).Where("email = ?", mail).Find(&user).Error return errors.Is(err, gorm.ErrRecordNotFound) } func (repo *UserRepository) Insert(user *models.User) error { err := repo.dbClient.Debug().Model(models.User{}).Create(user).Error if err != nil { log.Printf("failed to insert user: %v\n", err) return err } return nil }
I built the insert, register and CheckIfEmailExists functions for mongo:
func (repo *UserRepository) InsertInMongo(user *models.UserB) error { coll := repo.mongoClient.DB.Collection("users") _, err := coll.InsertOne(context.TODO(), user) if err != nil { log.Printf("failed to insert user: %v\n", err) return err } return nil } func (svc *UserService) RegisterToMongo(user *models.UserB) error { check := svc.userRepo.CheckIfEmailExistsInMongo(user.Email) if check { return errors.New("user already registered") } hash, err := svc.generatePasswordHash(user.Password) if err != nil { return errors.New("err can't register user") } user.Password = hash return svc.userRepo.InsertInMongo(user) } func (repo *UserRepository) CheckIfEmailExistsInMongo(email string) bool { coll := repo.mongoClient.Collection filter := bson.D{{Key: "email", Value: email}} count, err := coll.CountDocuments(context.TODO(), filter) if err != nil { panic(err) } if count != 0 { return true } return false }
You did not provide code on how to create UserService.
Ideally, you should have an interface that looks like this:
type UserRepository interface { CheckIfEmailExists(mail string) bool Insert(user *models.User) error … }
Then, the UserService should be created like this:
// We use the interface as param func NewUserService(userRepo UserRepository) UserService { return UserService{ UserRepo: userRepo } }
And you will have two separate repositories, both implementing the UserRepository
interface - this means they should have methods with the same name and same signature (parameters, return type) as the interface:
mongo_user_repository.go
Type MongoUserRepo struct { … } func (repo MongoUserRepo) CheckIfEmailExists(mail string) bool { … some mongo logic here } func (repo MongoUserRepo) Insert(user *models.User) error { … some mongo logic here }
postgres_user_repository.go
type PostgresUserRepo struct { … } func (repo PostgresUserRepo) CheckIfEmailExists(mail string) bool { … some postgres logic here } func (repo PostgresUserRepo) Insert(user *models.User) error { … some postgres logic here }
You can pass any of these depending on the use case, as in the (very bad) example below:
main.go
… var userService UserService if os.Getenv(“environment”) == “prod” { userService = NewUserService(postgreUserRepo) } else if os.Getenv(“environment”) == “dev” { userService = NewUserService(mongoUserRepo) }
The above is the detailed content of CRUD with Postgres and MongoDB?. For more information, please follow other related articles on the PHP Chinese website!