-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
User registration API #4
base: development
Are you sure you want to change the base?
Changes from 10 commits
0b829d6
9c09038
ed16e1d
56eb4dc
bac3c11
a5b58ef
232e8e4
9e91b82
b238b19
605e3bf
f75c135
395aa91
2ce2330
b66b748
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,13 +2,31 @@ package db | |
|
||
import ( | ||
"context" | ||
"database/sql" | ||
|
||
logger "github.com/sirupsen/logrus" | ||
) | ||
|
||
const ( | ||
insertUserQuery = `INSERT INTO users (first_name, last_name, email, mobile, country, state, city, address, password) | ||
VALUES (:first_name, :last_name, :email, :mobile, :country, :state, :city, :address, :password)` | ||
|
||
getUserByEmailQuery = `SELECT * FROM users WHERE email=$1 LIMIT 1` | ||
) | ||
|
||
// User - struct representing a user | ||
type User struct { | ||
Name string `db:"name" json:"full_name"` | ||
Age int `db:"age" json:"age"` | ||
ID int `db:"id" json:"id"` | ||
FirstName string `db:"first_name" json:"first_name"` | ||
LastName string `db:"last_name" json:"last_name"` | ||
Email string `db:"email" json:"email"` | ||
Mobile string `db:"mobile" json:"mobile"` | ||
Country string `db:"country" json:"country"` | ||
State string `db:"state" json:"state"` | ||
City string `db:"city" json:"city"` | ||
Address string `db:"address" json:"address"` | ||
Password string `db:"password" json:"password"` | ||
CreatedAt string `db:"created_at" json:"created_at"` | ||
} | ||
|
||
func (s *pgStore) ListUsers(ctx context.Context) (users []User, err error) { | ||
|
@@ -20,3 +38,36 @@ func (s *pgStore) ListUsers(ctx context.Context) (users []User, err error) { | |
|
||
return | ||
} | ||
|
||
// CreateNewUser = creates a new user in database | ||
func (s *pgStore) CreateUser(ctx context.Context, u User) (newUser User, err error) { | ||
stmt, err := s.db.PrepareNamed(insertUserQuery) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error while preparing user insert query") | ||
return | ||
} | ||
_, err = stmt.Exec(u) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s.db.NamedExec |
||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error while inserting user into database") | ||
return | ||
} | ||
newUser, err = s.GetUserByEmail(ctx, u.Email) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error selecting user from database with email: " + u.Email) | ||
return | ||
} | ||
return | ||
} | ||
|
||
// GetUserByEmail - Checks if user is present in DB and if then return user | ||
func (s *pgStore) GetUserByEmail(ctx context.Context, email string) (user User, err error) { | ||
err = s.db.Get(&user, getUserByEmailQuery, email) | ||
if err != nil { | ||
if err == sql.ErrNoRows { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have used |
||
return | ||
} | ||
logger.WithField("err", err.Error()).Error("Error while selecting user from database by email " + email) | ||
return | ||
} | ||
return | ||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE users; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
CREATE TABLE IF NOT EXISTS users ( | ||
id SERIAL NOT NULL PRIMARY KEY, | ||
first_name VARCHAR(255) NOT NULL, | ||
last_name VARCHAR(255), | ||
email VARCHAR(255) NOT NULL UNIQUE, | ||
mobile VARCHAR(20), | ||
country VARCHAR(100), | ||
state VARCHAR(100), | ||
city VARCHAR(100), | ||
address TEXT, | ||
password TEXT, | ||
created_at TIMESTAMP DEFAULT (NOW() AT TIME ZONE 'UTC') | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,23 @@ | ||
package service | ||
|
||
import ( | ||
"database/sql" | ||
"encoding/json" | ||
"io/ioutil" | ||
"joshsoftware/go-e-commerce/db" | ||
"net/http" | ||
|
||
logger "github.com/sirupsen/logrus" | ||
"golang.org/x/crypto/bcrypt" | ||
) | ||
|
||
type errorResponse struct { | ||
Error string `json:"error"` | ||
} | ||
type successResponse struct { | ||
Message string `json:"message"` | ||
} | ||
|
||
// @Title listUsers | ||
// @Description list all User | ||
// @Router /users [get] | ||
|
@@ -33,3 +44,88 @@ func listUsersHandler(deps Dependencies) http.HandlerFunc { | |
rw.Write(respBytes) | ||
}) | ||
} | ||
|
||
// @Title registerUser | ||
// @Description registers new user | ||
// @Router /register [post] | ||
// @Accept json | ||
// @Success 201 {object} | ||
// @Failure 400 {object} | ||
func registerUserHandler(deps Dependencies) http.HandlerFunc { | ||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { | ||
|
||
// reading data from body | ||
reqBody, err := ioutil.ReadAll(req.Body) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error in reading request body") | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
user := db.User{} | ||
err = json.Unmarshal(reqBody, &user) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error while Unmarshalling request json") | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
// For checking if user already registered | ||
_, err = deps.Store.GetUserByEmail(req.Context(), user.Email) | ||
|
||
// If check true then user is already registered | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. update the comment |
||
if err != sql.ErrNoRows && err == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only |
||
e := errorResponse{ | ||
Error: "user already registered", | ||
} | ||
respBytes, err := json.Marshal(e) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error while marshalling error msg ") | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
rw.Header().Add("Content-Type", "application/json") | ||
rw.WriteHeader(http.StatusBadRequest) | ||
rw.Write(respBytes) | ||
return | ||
} | ||
|
||
// For checking error occured while looking already registered user | ||
if err != nil && err != sql.ErrNoRows { | ||
logger.WithField("err", err.Error()).Error("Error while looking existing user") | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
// creating hash of the password | ||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), 8) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error while creating hash of the password") | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
user.Password = string(hashedPassword) | ||
|
||
// Storing new user's data in database | ||
_, err = deps.Store.CreateUser(req.Context(), user) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error in inserting user in database") | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
msg := successResponse{ | ||
Message: "user successfully registered", | ||
} | ||
respBytes, err := json.Marshal(msg) | ||
if err != nil { | ||
logger.WithField("err", err.Error()).Error("Error while marshalling success msg ") | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
rw.Header().Add("Content-Type", "application/json") | ||
rw.WriteHeader(http.StatusCreated) | ||
rw.Write(respBytes) | ||
return | ||
|
||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove commented code