refactor: Clean up and modularize service initialization in main.go

- Organize service initialization into helper functions
- Improve code readability and maintainability
This commit is contained in:
miaad shahrokhi 2024-01-29 01:09:32 +03:30 committed by hossein
parent 4943e90d77
commit 430bd9a95c
8 changed files with 238 additions and 85 deletions

6
go.mod
View File

@ -11,8 +11,10 @@ require (
github.com/knadh/koanf v1.5.0
github.com/labstack/echo-jwt/v4 v4.2.0
github.com/labstack/echo/v4 v4.11.4
github.com/oklog/ulid/v2 v2.1.0
github.com/redis/go-redis/v9 v9.4.0
github.com/rubenv/sql-migrate v1.6.0
golang.org/x/crypto v0.17.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
@ -21,7 +23,7 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
@ -31,10 +33,8 @@ require (
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/ulid/v2 v2.1.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect

3
go.sum
View File

@ -55,8 +55,9 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=

19
internal/initial/auth.go Normal file
View File

@ -0,0 +1,19 @@
package initial
import (
"git.gocasts.ir/ebhomengo/niki/config"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
)
type Auth struct {
BenefactorAuthSvc authservice.Service
AdminAuthSvc authservice.Service
}
func InitBenefactorAuthService(cfg config.Config) authservice.Service {
return authservice.New(cfg.Auth)
}
func InitAdminAuthService(cfg config.Config) authservice.Service {
return authservice.New(cfg.AdminAuth)
}

View File

@ -0,0 +1,37 @@
package initial
import (
"git.gocasts.ir/ebhomengo/niki/config"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
mysqladdress "git.gocasts.ir/ebhomengo/niki/repository/mysql/address"
mysqladmin "git.gocasts.ir/ebhomengo/niki/repository/mysql/admin"
mysqlkindbox "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box"
mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
)
type Databases struct {
BenefactorAddressDB *mysqladdress.DB
BenefactorKindBoxReqDB *mysqlkindboxreq.DB
KindBoxRepo *mysqlkindbox.DB
AdminMysql *mysqladmin.DB
}
func InitMysql(cfg config.Config) *mysql.DB {
return mysql.New(cfg.Mysql)
}
func InitBenefactorAddressDB(db *mysql.DB) *mysqladdress.DB {
return mysqladdress.New(db)
}
func InitBenefactorKindBoxReqDB(db *mysql.DB) *mysqlkindboxreq.DB {
return mysqlkindboxreq.New(db)
}
func InitKindBoxRepo(db *mysql.DB) *mysqlkindbox.DB {
return mysqlkindbox.New(db)
}
func InitAdminMysql(db *mysql.DB) *mysqladmin.DB {
return mysqladmin.New(db)
}

View File

@ -0,0 +1,62 @@
package initial
import (
"git.gocasts.ir/ebhomengo/niki/adapter/redis"
smsprovider "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider/kavenegar"
kavenegarotp "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider/kavenegar/otp"
"git.gocasts.ir/ebhomengo/niki/config"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
mysqladdress "git.gocasts.ir/ebhomengo/niki/repository/mysql/address"
mysqlbenefactor "git.gocasts.ir/ebhomengo/niki/repository/mysql/benefactor"
mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
redisotp "git.gocasts.ir/ebhomengo/niki/repository/redis/redis_otp"
adminservice "git.gocasts.ir/ebhomengo/niki/service/admin/admin"
adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
benefactoraddressservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/address"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
)
type Services struct {
BenefactorSvc benefactorservice.Service
BenefactorKindBoxReqSvc benefactorkindboxreqservice.Service
BenefactorAddressSvc benefactoraddressservice.Service
AdminKindBoxSvc adminkindboxservice.Service
AdminSvc adminservice.Service
AdminKindBoxReqSvc adminkindboxreqservice.Service
}
func initSms(cfg config.Config) *kavenegarotp.Adapter {
return kavenegarotp.New(smsprovider.New(cfg.KavenegarSmsProvider))
}
func InitAdminService(cfg config.Config, db *mysql.DB) adminservice.Service {
return adminservice.New(InitAdminMysql(db), InitAdminAuthService(cfg))
}
func InitBenefactorService(cfg config.Config, redisAdapter redis.Adapter, db *mysql.DB) benefactorservice.Service {
return benefactorservice.New(
cfg.BenefactorSvc,
redisotp.New(redisAdapter),
initSms(cfg),
InitBenefactorAuthService(cfg),
mysqlbenefactor.New(db),
)
}
func InitBenefactorAddressService(db *mysql.DB) benefactoraddressservice.Service {
return benefactoraddressservice.New(mysqladdress.New(db))
}
func InitBenefactorKindBoxReqService(db *mysql.DB) benefactorkindboxreqservice.Service {
return benefactorkindboxreqservice.New(mysqlkindboxreq.New(db))
}
func InitAdminKindBoxService(db *mysql.DB) adminkindboxservice.Service {
return adminkindboxservice.New(InitKindBoxRepo(db))
}
func InitAdminKindBoxReqService(db *mysql.DB) adminkindboxreqservice.Service {
return adminkindboxreqservice.New(InitBenefactorKindBoxReqDB(db), InitAdminKindBoxService(db))
}

View File

@ -0,0 +1,48 @@
package initial
import (
"git.gocasts.ir/ebhomengo/niki/adapter/redis"
"git.gocasts.ir/ebhomengo/niki/config"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
adminvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/admin"
adminkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box_req"
benefactoraddressvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/address"
benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor"
benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
)
type Validators struct {
BenefactorVld benefactorvalidator.Validator
BenefactorKindBoxReqVld benefactorkindboxreqvalidator.Validator
BenefactorAddressVld benefactoraddressvalidator.Validator
AdminKindBoxReqVld adminkindboxreqvalidator.Validator
AdminVld adminvalidator.Validator
}
func InitAdminKindBoxReqValidator(db *mysql.DB) adminkindboxreqvalidator.Validator {
return adminkindboxreqvalidator.New(InitBenefactorKindBoxReqDB(db))
}
func InitAdminValidator(db *mysql.DB) adminvalidator.Validator {
return adminvalidator.New(InitAdminMysql(db))
}
func InitBenefactorValidator() benefactorvalidator.Validator {
return benefactorvalidator.New()
}
func InitBenefactorKindBoxReqValidator(cfg config.Config, redisAdapter redis.Adapter, db *mysql.DB) benefactorkindboxreqvalidator.Validator {
return benefactorkindboxreqvalidator.New(
mysqlkindboxreq.New(db),
InitBenefactorService(cfg, redisAdapter, db),
InitBenefactorAddressService(db),
)
}
func InitBenefactorAddressValidator(cfg config.Config, redisAdapter redis.Adapter, db *mysql.DB) benefactoraddressvalidator.Validator {
return benefactoraddressvalidator.New(
InitBenefactorService(cfg, redisAdapter, db),
InitBenefactorAddressDB(db),
)
}

142
main.go
View File

@ -2,97 +2,83 @@ package main
import (
"git.gocasts.ir/ebhomengo/niki/adapter/redis"
smsprovider "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider/kavenegar"
kavenegarotp "git.gocasts.ir/ebhomengo/niki/adapter/sms_provider/kavenegar/otp"
"git.gocasts.ir/ebhomengo/niki/config"
httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
"git.gocasts.ir/ebhomengo/niki/internal/initial"
"git.gocasts.ir/ebhomengo/niki/repository/migrator"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
mysqladdress "git.gocasts.ir/ebhomengo/niki/repository/mysql/address"
mysqladmin "git.gocasts.ir/ebhomengo/niki/repository/mysql/admin"
mysqlbenefactor "git.gocasts.ir/ebhomengo/niki/repository/mysql/benefactor"
mysqlkindbox "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box"
mysqlkindboxreq "git.gocasts.ir/ebhomengo/niki/repository/mysql/kind_box_req"
redisotp "git.gocasts.ir/ebhomengo/niki/repository/redis/redis_otp"
adminservice "git.gocasts.ir/ebhomengo/niki/service/admin/admin"
adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
benefactoraddressservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/address"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/benefactor"
benefactorkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/kind_box_req"
adminvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/admin"
adminkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/admin/kind_box_req"
benefactoraddressvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/address"
benefactorvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/benefactor"
benefactorkindboxreqvalidator "git.gocasts.ir/ebhomengo/niki/validator/benefactor/kind_box_req"
_ "github.com/go-sql-driver/mysql"
)
type Dependencies struct {
initial.Auth
initial.Databases
initial.Validators
initial.Services
}
func main() {
cfg := config.C()
// TODO - add command for migrations
mgr := migrator.New(cfg.Mysql)
mgr.Up()
db := initDatabase(cfg)
redisAdapter := initRedis(cfg)
authSvc,
benefactorSvc,
benefactorVld,
benefactorKindBoxReqSvc,
benefactorKindBoxReqVld,
benefactorAddressSvc,
benefactorAddressVld,
adminSvc,
adminVld,
adminAuthSvc,
adminKindBoxReqSvc,
adminKindBoxReqVld := setupServices(cfg)
server := httpserver.New(cfg, benefactorSvc, benefactorVld, authSvc, benefactorKindBoxReqSvc, benefactorKindBoxReqVld,
benefactorAddressSvc, benefactorAddressVld, adminSvc, adminVld, adminAuthSvc, adminKindBoxReqSvc, adminKindBoxReqVld)
dependencies := initDependencies(cfg, redisAdapter, db)
initAndRunServer(cfg, dependencies)
}
func initDependencies(cfg config.Config, redisAdapter redis.Adapter, db *mysql.DB) *Dependencies {
return &Dependencies{
initial.Auth{
BenefactorAuthSvc: initial.InitBenefactorAuthService(cfg),
AdminAuthSvc: initial.InitAdminAuthService(cfg),
},
initial.Databases{
BenefactorAddressDB: initial.InitBenefactorAddressDB(db),
BenefactorKindBoxReqDB: initial.InitBenefactorKindBoxReqDB(db),
KindBoxRepo: initial.InitKindBoxRepo(db),
AdminMysql: initial.InitAdminMysql(db),
},
initial.Validators{
BenefactorVld: initial.InitBenefactorValidator(),
BenefactorKindBoxReqVld: initial.InitBenefactorKindBoxReqValidator(cfg, redisAdapter, db),
BenefactorAddressVld: initial.InitBenefactorAddressValidator(cfg, redisAdapter, db),
AdminKindBoxReqVld: initial.InitAdminKindBoxReqValidator(db),
AdminVld: initial.InitAdminValidator(db),
},
initial.Services{
BenefactorSvc: initial.InitBenefactorService(cfg, redisAdapter, db),
BenefactorKindBoxReqSvc: initial.InitBenefactorKindBoxReqService(db),
BenefactorAddressSvc: initial.InitBenefactorAddressService(db),
AdminKindBoxSvc: initial.InitAdminKindBoxService(db),
AdminKindBoxReqSvc: initial.InitAdminKindBoxReqService(db),
AdminSvc: initial.InitAdminService(cfg, db),
},
}
}
func initAndRunServer(cfg config.Config, dependencies *Dependencies) {
server := httpserver.New(cfg,
dependencies.BenefactorSvc, dependencies.BenefactorVld, dependencies.BenefactorAuthSvc,
dependencies.BenefactorKindBoxReqSvc, dependencies.BenefactorKindBoxReqVld,
dependencies.BenefactorAddressSvc, dependencies.BenefactorAddressVld,
dependencies.AdminSvc, dependencies.AdminVld, dependencies.AdminAuthSvc,
dependencies.AdminKindBoxReqSvc, dependencies.AdminKindBoxReqVld)
server.Serve()
}
//nolint:nakedret,gocritic // we are sure of this
func setupServices(cfg config.Config) (
benefactorAuthSvc authservice.Service, benefactorSvc benefactorservice.Service, benefactorVld benefactorvalidator.Validator,
benefactorKindBoxReqSvc benefactorkindboxreqservice.Service, benefactorKindBoxReqVld benefactorkindboxreqvalidator.Validator,
benefactorAddressSvc benefactoraddressservice.Service,
benefactorAddressVld benefactoraddressvalidator.Validator,
adminSvc adminservice.Service, adminVld adminvalidator.Validator,
adminAuthSvc authservice.Service,
adminKindBoxReqSvc adminkindboxreqservice.Service, adminKindBoxReqVld adminkindboxreqvalidator.Validator,
) {
benefactorAuthSvc = authservice.New(cfg.Auth)
func initDatabase(cfg config.Config) *mysql.DB {
migrateDatabase(cfg)
MysqlRepo := mysql.New(cfg.Mysql)
redisAdapter := redis.New(cfg.Redis)
RedisOtp := redisotp.New(redisAdapter)
benefactorMysql := mysqlbenefactor.New(MysqlRepo)
kavenegarSmsProvider := smsprovider.New(cfg.KavenegarSmsProvider)
otpSmsProvider := kavenegarotp.New(kavenegarSmsProvider)
authGenerator := authservice.New(cfg.Auth)
benefactorSvc = benefactorservice.New(cfg.BenefactorSvc, RedisOtp, otpSmsProvider, authGenerator, benefactorMysql)
benefactorAddressMysql := mysqladdress.New(MysqlRepo)
benefactorAddressSvc = benefactoraddressservice.New(benefactorAddressMysql)
benefactorAddressVld = benefactoraddressvalidator.New(benefactorSvc, benefactorAddressMysql)
benefactorVld = benefactorvalidator.New()
benefactorKindBoxReqMysql := mysqlkindboxreq.New(MysqlRepo)
benefactorKindBoxReqSvc = benefactorkindboxreqservice.New(benefactorKindBoxReqMysql)
benefactorKindBoxReqVld = benefactorkindboxreqvalidator.New(benefactorKindBoxReqMysql, benefactorSvc, benefactorAddressSvc)
mysqlkindboxRepo := mysqlkindbox.New(MysqlRepo)
adminkindboxsvc := adminkindboxservice.New(mysqlkindboxRepo)
adminKindBoxReqSvc = adminkindboxreqservice.New(benefactorKindBoxReqMysql, adminkindboxsvc)
adminKindBoxReqVld = adminkindboxreqvalidator.New(benefactorKindBoxReqMysql)
adminAuthSvc = authservice.New(cfg.AdminAuth)
adminMysql := mysqladmin.New(MysqlRepo)
adminVld = adminvalidator.New(adminMysql)
adminSvc = adminservice.New(adminMysql, adminAuthSvc)
return
return initial.InitMysql(cfg)
}
func initRedis(cfg config.Config) redis.Adapter {
return redis.New(cfg.Redis)
}
func migrateDatabase(cfg config.Config) {
migratorDB := migrator.New(cfg.Mysql)
migratorDB.Up()
}

View File

@ -26,13 +26,13 @@ func (s Service) Accept(ctx context.Context, req param.KindBoxReqAcceptRequest)
return param.KindBoxReqAcceptResponse{}, richerror.New(op).WithErr(gErr)
}
_, kErr := s.kindBoxClient.AddKindBoxAfterAcceptingRequest(ctx, adminkindboxparam.KindBoxAddAfterAcceptingReqRequest{
_, aErr := s.kindBoxClient.AddKindBoxAfterAcceptingRequest(ctx, adminkindboxparam.KindBoxAddAfterAcceptingReqRequest{
BenefactorID: kindBoxReq.BenefactorID,
KindBoxReqID: kindBoxReq.ID,
Type: kindBoxReq.KindBoxType,
Count: kindBoxReq.CountAccepted,
})
if kErr != nil {
if aErr != nil {
// rollback kind box request status
rErr := s.repo.RollbackKindBoxRequestStatus(ctx, req.ID)
if rErr != nil {
@ -40,7 +40,7 @@ func (s Service) Accept(ctx context.Context, req param.KindBoxReqAcceptRequest)
logger.L().Error(rErr.Error())
}
return param.KindBoxReqAcceptResponse{}, richerror.New(op).WithErr(kErr)
return param.KindBoxReqAcceptResponse{}, richerror.New(op).WithErr(aErr)
}
return param.KindBoxReqAcceptResponse{