made usage of first class citizen functions in go

This commit is contained in:
Jean Jacques Avril 2025-01-03 15:23:33 +00:00
parent e021ab7370
commit f151fa7eae
No known key found for this signature in database
5 changed files with 55 additions and 45 deletions

View File

@ -139,3 +139,7 @@ https://the-zen-of-go.netlify.app/
### FP-Go Documentation ### FP-Go Documentation
https://pkg.go.dev/github.com/IBM/fp-go https://pkg.go.dev/github.com/IBM/fp-go
https://betterprogramming.pub/investigate-functional-programming-concepts-in-go-1dada09bc913
https://rlee.dev/practical-guide-to-fp-ts-part-1

View File

@ -0,0 +1,14 @@
package repository
import (
"context"
E "github.com/IBM/fp-go/either"
)
// curried delegiert eine Methode mit Kontext und gibt eine Funktion zurück.
func curried[T any, R any](ctx context.Context, fn func(context.Context, T) E.Either[error, R]) func(T) E.Either[error, R] {
return func(input T) E.Either[error, R] {
return fn(ctx, input)
}
}

View File

@ -1,9 +1,8 @@
package repository package repository
import ( import (
"actatempus_backend/internal/domain/entities"
"actatempus_backend/internal/domain/repository"
"actatempus_backend/internal/domain/data" "actatempus_backend/internal/domain/data"
"actatempus_backend/internal/domain/entities"
"context" "context"
E "github.com/IBM/fp-go/either" E "github.com/IBM/fp-go/either"
@ -14,37 +13,32 @@ type UserRepositoryImpl struct {
dataSource data.UserDataSource dataSource data.UserDataSource
} }
// NewUserRepository creates a new instance of UserRepositoryImpl. // Create delegiert die Erstellung eines Benutzers an die Datenquelle.
func NewUserRepository(dataSource data.UserDataSource) repository.UserRepository { func (r *UserRepositoryImpl) Create(ctx context.Context) func(user entities.UserCreate) E.Either[error, entities.User] {
return &UserRepositoryImpl{dataSource: dataSource} return curried(ctx, r.dataSource.Create)
} }
// Create delegates the creation of a user to the data source. // FindByID delegiert das Abrufen eines Benutzers nach ID an die Datenquelle.
func (r *UserRepositoryImpl) Create(ctx context.Context, user entities.UserCreate) E.Either[error, entities.User] { func (r *UserRepositoryImpl) FindByID(ctx context.Context) func(id string) E.Either[error, entities.User] {
return r.dataSource.Create(ctx, user) return curried(ctx, r.dataSource.FindByID)
} }
// FindByID delegates fetching a user by ID to the data source. // FindByEmail delegiert das Abrufen eines Benutzers nach E-Mail an die Datenquelle.
func (r *UserRepositoryImpl) FindByID(ctx context.Context, id string) E.Either[error, entities.User] { func (r *UserRepositoryImpl) FindByEmail(ctx context.Context) func(email string) E.Either[error, entities.User] {
return r.dataSource.FindByID(ctx, id) return curried(ctx, r.dataSource.FindByEmail)
} }
// FindByEmail delegates fetching a user by email to the data source. // Update delegiert das Aktualisieren eines Benutzers an die Datenquelle.
func (r *UserRepositoryImpl) FindByEmail(ctx context.Context, email string) E.Either[error, entities.User] { func (r *UserRepositoryImpl) Update(ctx context.Context) func(user entities.UserUpdate) E.Either[error, entities.User] {
return r.dataSource.FindByEmail(ctx, email) return curried(ctx, r.dataSource.Update)
} }
// Update delegates updating a user to the data source. // Delete delegiert das Löschen eines Benutzers an die Datenquelle.
func (r *UserRepositoryImpl) Update(ctx context.Context, user entities.UserUpdate) E.Either[error, entities.User] { func (r *UserRepositoryImpl) Delete(ctx context.Context) func(id string) E.Either[error, entities.User] {
return r.dataSource.Update(ctx, user) return curried(ctx, r.dataSource.Delete)
} }
// Delete delegates deleting a user to the data source. // FindAll delegiert das Abrufen aller Benutzer an die Datenquelle.
func (r *UserRepositoryImpl) Delete(ctx context.Context, id string) E.Either[error, entities.User] {
return r.dataSource.Delete(ctx, id)
}
// FindAll delegates fetching all users to the data source.
func (r *UserRepositoryImpl) FindAll(ctx context.Context) E.Either[error, []entities.User] { func (r *UserRepositoryImpl) FindAll(ctx context.Context) E.Either[error, []entities.User] {
return r.dataSource.FindAll(ctx) return r.dataSource.FindAll(ctx)
} }

View File

@ -38,9 +38,9 @@ func (s *UserService) CreateUser(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return return
} }
userCreate := mappers.MapCreateDTOToUser(userCreateDTO) F.Pipe3(
F.Pipe2( mappers.MapCreateDTOToUser(userCreateDTO),
s.repository.Create(c.Request.Context(), userCreate), s.repository.Create(c.Request.Context()),
E.Map[error](mappers.MapUserToDTO), E.Map[error](mappers.MapUserToDTO),
E.Fold( E.Fold(
HandleError(c), HandleError(c),
@ -51,9 +51,9 @@ func (s *UserService) CreateUser(c *gin.Context) {
// GetUserByID handles fetching a user by their ID. // GetUserByID handles fetching a user by their ID.
func (s *UserService) GetUserByID(c *gin.Context) { func (s *UserService) GetUserByID(c *gin.Context) {
id := c.Param("id") F.Pipe3(
F.Pipe2( c.Param("id"),
s.repository.FindByID(c.Request.Context(), id), s.repository.FindByID(c.Request.Context()),
E.Map[error](mappers.MapUserToDTO), E.Map[error](mappers.MapUserToDTO),
E.Fold( E.Fold(
HandleError(c), HandleError(c),
@ -84,10 +84,9 @@ func (s *UserService) UpdateUser(c *gin.Context) {
return return
} }
userUpdate := mappers.MapUpdateDTOToUser(userUpdateDTO, id) F.Pipe3(
mappers.MapUpdateDTOToUser(userUpdateDTO, id),
F.Pipe2( s.repository.Update(c.Request.Context()),
s.repository.Update(c.Request.Context(), userUpdate),
E.Map[error](mappers.MapUserToDTO), E.Map[error](mappers.MapUserToDTO),
E.Fold( E.Fold(
HandleError(c), HandleError(c),
@ -98,15 +97,13 @@ func (s *UserService) UpdateUser(c *gin.Context) {
// DeleteUser handles deleting a user by their ID. // DeleteUser handles deleting a user by their ID.
func (s *UserService) DeleteUser(c *gin.Context) { func (s *UserService) DeleteUser(c *gin.Context) {
id := c.Param("id") F.Pipe3(
c.Param("id"),
F.Pipe2( s.repository.Delete(c.Request.Context()),
s.repository.Delete(c.Request.Context(), id),
E.Map[error](mappers.MapUserToDTO), E.Map[error](mappers.MapUserToDTO),
E.Fold( E.Fold(
HandleError(c), HandleError(c),
HandleSuccess[dto.UserDTO](c, http.StatusOK), HandleSuccess[dto.UserDTO](c, http.StatusOK),
), ),
) )
} }

View File

@ -8,11 +8,12 @@ import (
) )
// UserRepository defines the operations for interacting with user data. // UserRepository defines the operations for interacting with user data.
type UserRepository interface { type UserRepository interface {
Create(ctx context.Context, user entities.UserCreate) E.Either[error,entities.User] Create(ctx context.Context) func(user entities.UserCreate) E.Either[error, entities.User]
FindByID(ctx context.Context, id string) E.Either[error,entities.User] FindByID(ctx context.Context) func(id string) E.Either[error, entities.User]
FindByEmail(ctx context.Context, email string) E.Either[error,entities.User] FindByEmail(ctx context.Context) func(email string) E.Either[error, entities.User]
Update(ctx context.Context, user entities.UserUpdate) E.Either[error,entities.User] Update(ctx context.Context) func(user entities.UserUpdate) E.Either[error, entities.User]
Delete(ctx context.Context, id string) E.Either[error,entities.User] Delete(ctx context.Context) func(id string) E.Either[error, entities.User]
FindAll(ctx context.Context) E.Either[error,[]entities.User] FindAll(ctx context.Context) E.Either[error, []entities.User] // Keine zusätzlichen Argumente nötig
} }