From b5c851c0187b064f2bea03342687e716626f890f Mon Sep 17 00:00:00 2001 From: Jean Jacques Avril Date: Fri, 3 Jan 2025 14:54:39 +0000 Subject: [PATCH] Implemented User Repository in a functional manner by making use of IBMs fp-go package --- .../internal/application/services/helpers.go | 21 ++++ .../services/mapper/user_dto_mapper.go | 9 ++ .../application/services/user_service.go | 97 +++++++++---------- 3 files changed, 78 insertions(+), 49 deletions(-) create mode 100644 backend-go/internal/application/services/helpers.go diff --git a/backend-go/internal/application/services/helpers.go b/backend-go/internal/application/services/helpers.go new file mode 100644 index 0000000..6f34f1e --- /dev/null +++ b/backend-go/internal/application/services/helpers.go @@ -0,0 +1,21 @@ +package services + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func HandleError(c *gin.Context) func(error) any { + return func(err error) any { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return nil + } +} + +func HandleSuccess[T any](c *gin.Context, statusCode int) func(T) any { + return func(data T) any { + c.JSON(statusCode, data) + return nil + } +} \ No newline at end of file diff --git a/backend-go/internal/application/services/mapper/user_dto_mapper.go b/backend-go/internal/application/services/mapper/user_dto_mapper.go index 1d6e761..6ed3d26 100644 --- a/backend-go/internal/application/services/mapper/user_dto_mapper.go +++ b/backend-go/internal/application/services/mapper/user_dto_mapper.go @@ -17,6 +17,15 @@ func MapUserToDTO(user entities.User) dto.UserDTO { } } +// MapUsersToDTOs converts a slice of User domain objects to a slice of UserDTOs. +func MapUsersToDTOs(users []entities.User) []dto.UserDTO { + var userDTOs []dto.UserDTO + for _, user := range users { + userDTOs = append(userDTOs, MapUserToDTO(user)) + } + return userDTOs +} + // MapCreateDTOToUser converts a UserCreateDTO to a User domain object. func MapCreateDTOToUser(dto dto.UserCreateDTO) entities.UserCreate { return entities.UserCreate{ diff --git a/backend-go/internal/application/services/user_service.go b/backend-go/internal/application/services/user_service.go index 30fd82c..5576441 100644 --- a/backend-go/internal/application/services/user_service.go +++ b/backend-go/internal/application/services/user_service.go @@ -1,15 +1,16 @@ -package service +package services import ( + "actatempus_backend/internal/application/services/dto" mappers "actatempus_backend/internal/application/services/mapper" "actatempus_backend/internal/domain/entities" "actatempus_backend/internal/domain/repository" "net/http" - "github.com/gin-gonic/gin" - + A "github.com/IBM/fp-go/array" E "github.com/IBM/fp-go/either" F "github.com/IBM/fp-go/function" + "github.com/gin-gonic/gin" ) // UserService handles user-related HTTP requests. @@ -33,71 +34,68 @@ func (s *UserService) RegisterRoutes(router *gin.RouterGroup) { // CreateUser handles the creation of a new user. func (s *UserService) CreateUser(c *gin.Context) { - var userCreate entities.UserCreate - if err := c.ShouldBindJSON(&userCreate); err != nil { + var userCreateDTO dto.UserCreateDTO + if err := c.ShouldBindJSON(&userCreateDTO); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - - s.repository.Create(c.Request.Context(), userCreate).Fold( - func(err error) { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - }, - func(user entities.User) { - c.JSON(http.StatusCreated, user) - }, + userCreate := mappers.MapCreateDTOToUser(userCreateDTO) + F.Pipe2( + s.repository.Create(c.Request.Context(), userCreate), + E.Map[error](mappers.MapUserToDTO), + E.Fold( + HandleError(c), + HandleSuccess[dto.UserDTO](c, http.StatusCreated), + ), ) } // GetUserByID handles fetching a user by their ID. func (s *UserService) GetUserByID(c *gin.Context) { id := c.Param("id") - mappers.MapCreateDTOToProject(id) - res := F.Pipe2( + F.Pipe2( s.repository.FindByID(c.Request.Context(), id), - E.Map(mappers.MapUserToDTO), - ) - - s.repository.FindByID(c.Request.Context(), id).Fold( - func(err error) { - c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) - }, - func(user entities.User) { - c.JSON(http.StatusOK, user) - }, + E.Map[error](mappers.MapUserToDTO), + E.Fold( + HandleError(c), + HandleSuccess[dto.UserDTO](c, http.StatusOK), + ), ) } // GetAllUsers handles fetching all users. func (s *UserService) GetAllUsers(c *gin.Context) { - s.repository.FindAll(c.Request.Context()).Fold( - func(err error) { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - }, - func(users []entities.User) { - c.JSON(http.StatusOK, users) - }, + F.Pipe2( + s.repository.FindAll(c.Request.Context()), + E.Map[error](func(users []entities.User) []dto.UserDTO { + return A.Map(mappers.MapUserToDTO)(users) // Anwenden des Mappings auf jedes Element + }), + E.Fold( + HandleError(c), + HandleSuccess[[]dto.UserDTO](c, http.StatusOK), + ), ) } // UpdateUser handles updating an existing user. func (s *UserService) UpdateUser(c *gin.Context) { id := c.Param("id") - var userUpdate entities.UserUpdate + var userUpdateDTO dto.UserUpdateDTO - if err := c.ShouldBindJSON(&userUpdate); err != nil { + if err := c.ShouldBindJSON(&userUpdateDTO); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - userUpdate.ID = id - s.repository.Update(c.Request.Context(), userUpdate).Fold( - func(err error) { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - }, - func(user entities.User) { - c.JSON(http.StatusOK, user) - }, + userUpdate := mappers.MapUpdateDTOToUser(userUpdateDTO, id) + + F.Pipe2( + s.repository.Update(c.Request.Context(), userUpdate), + E.Map[error](mappers.MapUserToDTO), + E.Fold( + HandleError(c), + HandleSuccess[dto.UserDTO](c, http.StatusOK), + ), ) } @@ -105,12 +103,13 @@ func (s *UserService) UpdateUser(c *gin.Context) { func (s *UserService) DeleteUser(c *gin.Context) { id := c.Param("id") - s.repository.Delete(c.Request.Context(), id).Fold( - func(err error) { - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) - }, - func(_ entities.User) { - c.JSON(http.StatusOK, gin.H{"message": "User deleted successfully"}) - }, + F.Pipe2( + s.repository.Delete(c.Request.Context(), id), + E.Map[error](mappers.MapUserToDTO), + E.Fold( + HandleError(c), + HandleSuccess[dto.UserDTO](c, http.StatusOK), + ), ) + }