diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index abe6514..c422ba6 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ # Go workspace file go.work -.DS_Store \ No newline at end of file +.DS_Store +test.db \ No newline at end of file diff --git a/common/response.go b/common/response.go new file mode 100644 index 0000000..de5f132 --- /dev/null +++ b/common/response.go @@ -0,0 +1,32 @@ +package common + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +type requestResponse struct { + Message string `json:"message"` + Status uint `json:"status"` +} + +func SuccessResponse(ctx *gin.Context, msg string) { + + response := requestResponse{ + msg, + http.StatusOK, + } + + ctx.JSON(http.StatusOK, response) +} + +func BadResponse(ctx *gin.Context, msg string) { + + response := requestResponse{ + msg, + http.StatusBadRequest, + } + + ctx.JSON(http.StatusBadRequest, response) +} diff --git a/common/user.go b/common/user.go index 86a57c8..e28d3a7 100644 --- a/common/user.go +++ b/common/user.go @@ -1,10 +1,18 @@ package common type UserCreationInput struct { - FullName string `json:"full_name"` + FullName string `json:"fullName"` + Email string `json:"email"` +} +type UserUpdateInput struct { + FullName string `json:"fullName"` Email string `json:"email"` } func NewUserCreationInput() *UserCreationInput { return &UserCreationInput{} } + +func NewUserUpdateInput() *UserUpdateInput { + return &UserUpdateInput{} +} diff --git a/frontend/src/components/createUser.js b/frontend/src/components/createUser.js index 9e99267..8862dad 100644 --- a/frontend/src/components/createUser.js +++ b/frontend/src/components/createUser.js @@ -7,11 +7,11 @@ export default function CreateUser() { console.log(fullName); console.log(email); - fetch("https://jsonplaceholder.typicode.com/users", { + fetch("http://localhost:8080/api/users/", { method: "POST", body: JSON.stringify({ - fullName, - email, + "fullName":fullName, + "email":email, }), headers: { "Content-type": "application/json; charset=UTF-8", diff --git a/frontend/src/components/userlist.js b/frontend/src/components/userlist.js index aef2814..8ed63f4 100644 --- a/frontend/src/components/userlist.js +++ b/frontend/src/components/userlist.js @@ -7,7 +7,7 @@ export default function UserList() { function reloadUserList(event){ console.log(event); - fetch("http://localhost:8080/api/users", { + fetch("http://localhost:8080/api/users/", { method: "GET", headers: { "Content-type": "application/json; charset=UTF-8", @@ -40,7 +40,7 @@ export default function UserList() { { data.map((item)=>( - + )) } diff --git a/handlers/user.go b/handlers/user.go index 1fb9abd..c22ef71 100644 --- a/handlers/user.go +++ b/handlers/user.go @@ -11,36 +11,119 @@ import ( type UserHandler struct { groupName string - userManager *managers.UserManager + userManager managers.UserManager } -func NewUserHandlerFrom(userManager *managers.UserManager) *UserHandler { +func NewUserHandlerFrom(userManager managers.UserManager) *UserHandler { return &UserHandler{ "api/users", userManager, } } -func (userHandler *UserHandler) RegisterUserApis(r *gin.Engine) { - userGroup := r.Group(userHandler.groupName) - userGroup.POST("", userHandler.Create) +func (handler *UserHandler) RegisterUserApis(r *gin.Engine) { + userGroup := r.Group(handler.groupName) + + userGroup.POST("", handler.Create) + userGroup.GET("", handler.List) + userGroup.GET(":userid/", handler.Detail) + userGroup.DELETE(":userid/", handler.Delete) + userGroup.PATCH(":userid/", handler.Update) } -func (userHandler *UserHandler) Create(ctx *gin.Context) { +func (handler *UserHandler) Create(ctx *gin.Context) { userData := common.NewUserCreationInput() err := ctx.BindJSON(&userData) if err != nil { - fmt.Println("Failed to bind data") + common.BadResponse(ctx, "Failed to bind data") + return } - newUser, err := userHandler.userManager.Create(userData) + newUser, err := handler.userManager.Create(userData) if err != nil { - fmt.Println("failed to create user") + common.BadResponse(ctx, "failed to create user") + return } ctx.JSON(http.StatusOK, newUser) } + +func (handler *UserHandler) List(ctx *gin.Context) { + + allUsers, err := handler.userManager.List() + + if err != nil { + common.BadResponse(ctx, "failed to get users") + return + } + + ctx.JSON(http.StatusOK, allUsers) +} + +func (handler *UserHandler) Detail(ctx *gin.Context) { + + userId, ok := ctx.Params.Get("userid") + + if !ok { + fmt.Println("invalid userid") + } + user, err := handler.userManager.Get(userId) + + if user.ID == 0 { + common.BadResponse(ctx, "no user present") + return + } + + if err != nil { + common.BadResponse(ctx, "failed to get user") + } + + ctx.JSON(http.StatusOK, user) +} + +func (handler *UserHandler) Delete(ctx *gin.Context) { + + userId, ok := ctx.Params.Get("userid") + + if !ok { + common.BadResponse(ctx, "invalid userid") + } + err := handler.userManager.Delete(userId) + + if err != nil { + common.BadResponse(ctx, "failed to delete user") + } + + common.SuccessResponse(ctx, "Deleted user") +} + +func (handler *UserHandler) Update(ctx *gin.Context) { + + userId, ok := ctx.Params.Get("userid") + + if !ok { + common.BadResponse(ctx, "failed to delete user") + } + + userData := common.NewUserUpdateInput() + + err := ctx.BindJSON(&userData) + + if err != nil { + common.BadResponse(ctx, "failed to bind data") + return + } + + user, err := handler.userManager.Update(userId, userData) + + if err != nil { + common.BadResponse(ctx, "failed to update user") + return + } + + ctx.JSON(http.StatusOK, user) +} diff --git a/main.go b/main.go index e5e4449..077bdc1 100644 --- a/main.go +++ b/main.go @@ -3,14 +3,14 @@ package main import ( "fmt" - "github.com/buildfromzero/skill-map/database" "github.com/buildfromzero/skill-map/handlers" "github.com/buildfromzero/skill-map/managers" + "github.com/buildfromzero/skill-map/storage" "github.com/gin-gonic/gin" ) func init() { - database.Initialize() + storage.InitializeDatabase() } func main() { diff --git a/managers/user.go b/managers/user.go index 23a4141..1a0a34a 100644 --- a/managers/user.go +++ b/managers/user.go @@ -4,21 +4,30 @@ import ( "errors" "github.com/buildfromzero/skill-map/common" - "github.com/buildfromzero/skill-map/database" "github.com/buildfromzero/skill-map/models" + "github.com/buildfromzero/skill-map/storage" ) -type UserManager struct { +type UserManager interface { + Create(userData *common.UserCreationInput) (*models.User, error) + List() ([]models.User, error) + Get(id string) (models.User, error) + Update(userId string, userData *common.UserUpdateInput) (*models.User, error) + Delete(id string) error +} + +type userManager struct { + // DatabaseDriver // dbClient } -func NewUserManager() *UserManager { - return &UserManager{} +func NewUserManager() UserManager { + return &userManager{} } -func (userMgr *UserManager) Create(userData *common.UserCreationInput) (*models.User, error) { +func (userMgr *userManager) Create(userData *common.UserCreationInput) (*models.User, error) { newUser := &models.User{FullName: userData.FullName, Email: userData.Email} - database.DB.Create(newUser) + storage.DB.Create(newUser) if newUser.ID == 0 { return nil, errors.New("user creation failed") @@ -26,3 +35,35 @@ func (userMgr *UserManager) Create(userData *common.UserCreationInput) (*models. return newUser, nil } + +func (userMgr *userManager) List() ([]models.User, error) { + users := []models.User{} + storage.DB.Find(&users) + return users, nil +} + +func (userMgr *userManager) Get(id string) (models.User, error) { + user := models.User{} + + storage.DB.First(&user, id) + + return user, nil +} + +func (userMgr *userManager) Update(userId string, userData *common.UserUpdateInput) (*models.User, error) { + + user := models.User{} + + storage.DB.First(&user, userId) + storage.DB.Model(&user).Updates(models.User{FullName: userData.FullName, Email: userData.Email}) + + return &user, nil +} + +func (userMgr *userManager) Delete(id string) error { + user := models.User{} + + storage.DB.First(&user, id) + storage.DB.Delete(&user) + return nil +} diff --git a/models/user.go b/models/user.go index 9b5b014..7ed6851 100644 --- a/models/user.go +++ b/models/user.go @@ -1,9 +1,17 @@ package models -import "gorm.io/gorm" +import ( + "time" + + "gorm.io/gorm" +) type User struct { - gorm.Model - FullName string - Email string + // gorm.Model + ID uint `gorm:"primarykey" json:"id"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` + FullName string `json:"fullName"` + Email string `json:"email"` } diff --git a/database/db.go b/storage/db.go similarity index 86% rename from database/db.go rename to storage/db.go index 7aad781..bb63b7b 100644 --- a/database/db.go +++ b/storage/db.go @@ -1,4 +1,4 @@ -package database +package storage import ( "github.com/buildfromzero/skill-map/models" @@ -8,7 +8,7 @@ import ( var DB *gorm.DB -func Initialize() { +func InitializeDatabase() { var err error DB, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) if err != nil { diff --git a/test.db b/test.db deleted file mode 100644 index b1acf07..0000000 Binary files a/test.db and /dev/null differ