diff --git a/trading_assistant_api/common/types/response.go b/trading_assistant_api/common/types/response.go index 29ab357..c5e5f0e 100644 --- a/trading_assistant_api/common/types/response.go +++ b/trading_assistant_api/common/types/response.go @@ -3,4 +3,5 @@ package types type Response struct { Status bool `json:"status"` Message string `json:"message"` + Data interface{} `json:"data,omitempty"` } diff --git a/trading_assistant_api/services/user/main.go b/trading_assistant_api/services/user/main.go index e8e8ac7..39d39dd 100644 --- a/trading_assistant_api/services/user/main.go +++ b/trading_assistant_api/services/user/main.go @@ -67,12 +67,10 @@ func main() { func routes() http.Handler { mux := http.NewServeMux() mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - w.Write([]byte("ok")) + writeJSON(w, http.StatusOK, true, "ok", nil) }) mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - w.Write([]byte("user-service v0.1.0")) + writeJSON(w, http.StatusOK, true, "ok", map[string]string{"version": "user-service v0.1.0"}) }) mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello from user-service") @@ -96,26 +94,26 @@ type loginResp struct { func registerHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { - writeJSON(w, http.StatusMethodNotAllowed, false, "method not allowed") + writeJSON(w, http.StatusMethodNotAllowed, false, "method not allowed", nil) return } var req registerReq if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - writeJSON(w, http.StatusBadRequest, false, "invalid json") + writeJSON(w, http.StatusBadRequest, false, "invalid json", nil) return } if !validAccount(req.Account) || !validPassword(req.Password) { - writeJSON(w, http.StatusBadRequest, false, "invalid account or password") + writeJSON(w, http.StatusBadRequest, false, "invalid account or password", nil) return } hashed, err := bcrypt.GenerateFromPassword([]byte(req.Password), 12) if err != nil { - writeJSON(w, http.StatusInternalServerError, false, "internal error") + writeJSON(w, http.StatusInternalServerError, false, "internal error", nil) return } tx, err := pg.Begin() if err != nil { - writeJSON(w, http.StatusInternalServerError, false, "internal error") + writeJSON(w, http.StatusInternalServerError, false, "internal error", nil) return } defer func() { @@ -123,57 +121,57 @@ func registerHandler(w http.ResponseWriter, r *http.Request) { }() var userID string if err := tx.QueryRow(`INSERT INTO users DEFAULT VALUES RETURNING user_id`).Scan(&userID); err != nil { - writeJSON(w, http.StatusInternalServerError, false, "internal error") + writeJSON(w, http.StatusInternalServerError, false, "internal error", nil) return } if _, err := tx.Exec(`INSERT INTO user_login_accounts (user_id, value, deleted) VALUES ($1, $2, false)`, userID, req.Account); err != nil { if isUniqueViolation(err) { - writeJSON(w, http.StatusConflict, false, "account exists") + writeJSON(w, http.StatusConflict, false, "account exists", nil) return } - writeJSON(w, http.StatusInternalServerError, false, "internal error") + writeJSON(w, http.StatusInternalServerError, false, "internal error", nil) return } if _, err := tx.Exec(`INSERT INTO user_login_passwords (user_id, value, deleted) VALUES ($1, $2, false)`, userID, string(hashed)); err != nil { - writeJSON(w, http.StatusInternalServerError, false, "internal error") + writeJSON(w, http.StatusInternalServerError, false, "internal error", nil) return } if err := tx.Commit(); err != nil { - writeJSON(w, http.StatusInternalServerError, false, "internal error") + writeJSON(w, http.StatusInternalServerError, false, "internal error", nil) return } - writeJSON(w, http.StatusCreated, true, userID) + writeJSON(w, http.StatusCreated, true, "ok", map[string]string{"user_id": userID}) } func loginHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { - writeJSON(w, http.StatusMethodNotAllowed, false, "method not allowed") + writeJSON(w, http.StatusMethodNotAllowed, false, "method not allowed", nil) return } var req loginReq if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - writeJSON(w, http.StatusBadRequest, false, "invalid json") + writeJSON(w, http.StatusBadRequest, false, "invalid json", nil) return } if !validAccount(req.Account) || !validPassword(req.Password) { - writeJSON(w, http.StatusBadRequest, false, "invalid account or password") + writeJSON(w, http.StatusBadRequest, false, "invalid account or password", nil) return } var userID string if err := pg.QueryRow(`SELECT user_id FROM user_login_accounts WHERE value = $1 AND deleted = false`, req.Account).Scan(&userID); err != nil { - writeJSON(w, http.StatusUnauthorized, false, "unauthorized") + writeJSON(w, http.StatusUnauthorized, false, "unauthorized", nil) return } var hashed string if err := pg.QueryRow(`SELECT value FROM user_login_passwords WHERE user_id = $1 AND deleted = false`, userID).Scan(&hashed); err != nil { - writeJSON(w, http.StatusUnauthorized, false, "unauthorized") + writeJSON(w, http.StatusUnauthorized, false, "unauthorized", nil) return } if bcrypt.CompareHashAndPassword([]byte(hashed), []byte(req.Password)) != nil { - writeJSON(w, http.StatusUnauthorized, false, "unauthorized") + writeJSON(w, http.StatusUnauthorized, false, "unauthorized", nil) return } - writeJSON(w, http.StatusOK, true, userID) + writeJSON(w, http.StatusOK, true, "ok", map[string]string{"user_id": userID}) } func validAccount(a string) bool { @@ -205,8 +203,8 @@ func applySchema(path string) error { return err } -func writeJSON(w http.ResponseWriter, code int, status bool, msg string) { +func writeJSON(w http.ResponseWriter, code int, status bool, msg string, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) - json.NewEncoder(w).Encode(types.Response{Status: status, Message: msg}) + json.NewEncoder(w).Encode(types.Response{Status: status, Message: msg, Data: data}) }