Golangを独学で学習しているものです。
ぜひお力を貸して頂けると幸いです。
● 現在の状況
golangでDIを実装したい(モックテストを実現するため)
● 困っていること
参考書などを引用してコードを実装↓
gormを使用しており、DIするためにハンドラーにdbを渡した。
main.go
main.go
1 2func signupHandler(user models.UserService) http.HandlerFunc { 3 return func(w http.ResponseWriter, r *http.Request) { 4 var u models.User 5 json.NewDecoder(r.Body).Decode(&u) 6 7 name := u.UserName 8 email := u.Email 9 pass := u.Password 10 11 if name == "" { 12 apiError(w, "UserName is required", http.StatusBadRequest) 13 return 14 } 15 if email == "" { 16 apiError(w, "Email is required", http.StatusBadRequest) 17 return 18 } 19 if pass == "" { 20 apiError(w, "Password is required", http.StatusBadRequest) 21 return 22 } 23 24 if err := user.CreateUser(name, email, pass); err != nil { 25 apiError(w, "username or email are duplicated", http.StatusConflict) 26 return 27 } 28 29 apiError(w, "success", http.StatusCreated) 30 return 31 } 32} 33 34func userDeleteHandler(user models.UserService) http.HandlerFunc { 35 return func(w http.ResponseWriter, r *http.Request) { 36 var u models.User 37 json.NewDecoder(r.Body).Decode(&u) 38 39 id, err := strconv.Atoi(path.Base(r.URL.Path)) 40 if err != nil { 41 apiError(w, "cloud not find user", http.StatusNotFound) 42 return 43 } 44 err = user.DeleteUser(id, u.Password) 45 if err != nil { 46 apiError(w, err.Error(), http.StatusBadRequest) 47 return 48 } 49 apiError(w, "success", http.StatusOK) 50 return 51 } 52} 53 54func StartWebServer() error { 55 db, err := db.SQLConnect() 56 if err != nil { 57 panic(err.Error()) 58 } 59 defer db.Close() 60 61 r := mux.NewRouter() 62 http.Handle("/", r) 63 64 // users 65 r.HandleFunc("/users", signupHandler(&models.User{DB: db})).Methods("POST") 66 r.HandleFunc("/users/{id:[0-9]+}", userDeleteHandler(&models.User{DB: db})).Methods("DELETE") 67 68 return http.ListenAndServe(fmt.Sprintf(":%d", config.Config.Port), nil) 69}
models.go
1type UserService interface { 2 CreateUser(name string, email string, pass string) (err error) 3 DeleteUser(id int, pass string) (err error) 4} 5 6// User 構造体 7type User struct { 8 DB *gorm.DB 9 ID int `json:"id,omitempty" gorm:"primaryKey,unique"` 10 UserName string `json:"user_name,omitempty" gorm:"unique"` 11 Email string `json:"email,omitempty" gorm:"unique"` 12 Password string `json:"password,omitempty"` 13 CreatedAt time.Time `json:"created_at,omitempty"` 14 UpdatedAt time.Time `json:"updated_at,omitempty"` 15} 16 17// CreateUser user登録 18func (user *User) CreateUser(name, email, pass string) (err error) { 19 user.ID = 0 //gorm auto increment 20 user.UserName = name 21 user.Email = email 22 user.CreatedAt = time.Now() 23 user.UpdatedAt = time.Now() 24 25 hash, err := bcrypt.GenerateFromPassword([]byte(pass), 10) 26 if err != nil { 27 log.Fatal(err) 28 } 29 user.Password = string(hash) 30 31 if err := user.DB.Create(&user).Error; err != nil { 32 return err 33 } 34 35 return 36} 37 38func (user *User) DeleteUser(id int, pass string) (err error) { 39 if err := user.DB.First(&user, id).Error; err != nil { 40 return err 41 } 42 43 if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(pass)); err != nil { 44 return err 45 } 46 47 if err := user.DB.Delete(&user).Error; err != nil { 48 return err 49 } 50 return nil 51}
エラー
apiを叩くと1度しか成功しない。
1度目に叩い情報が構造体に残ったままになってしまう。
質問
apiを叩くと1回目の処理は成功するが、2回目以降の処理は1度目に叩いた情報が残っているので毎回初期化しないといけないのでしょうか?
CreateUserメソッドではIDに0を渡すことで無理やりIDを初期化しております。
ID = 0
を書かなければ user.ID duplicate
のエラーが出てしまいます。
DIしない場合はSQL処理の度にdb.Close()しているため毎回初期化されると予想しております。
箇条書きで羅列してしまいましたが、以上でぜひお力をお借りしたいです>_<
どうぞよろしくお願いいたします!
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/17 23:22