Skip to content

Commit 0ed538d

Browse files
Merge pull request #20 from DoWithLogic/feat/tidy-up
chore: tidy up code and make package imple interfaces
2 parents ad4e848 + 694fd42 commit 0ed538d

File tree

13 files changed

+88
-144
lines changed

13 files changed

+88
-144
lines changed

internal/app/app.go

+13-18
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package app
33
import (
44
"context"
55
"fmt"
6-
"net/http"
76
"os"
87

98
_ "github.com/go-sql-driver/mysql"
@@ -17,10 +16,10 @@ import (
1716
)
1817

1918
type App struct {
20-
DB *sqlx.DB
21-
Echo *echo.Echo
22-
Log *zerolog.Logger
23-
Cfg config.Config
19+
db *sqlx.DB
20+
echo *echo.Echo
21+
log *zerolog.Logger
22+
cfg config.Config
2423
}
2524

2625
func NewApp(ctx context.Context, cfg config.Config) *App {
@@ -30,27 +29,23 @@ func NewApp(ctx context.Context, cfg config.Config) *App {
3029
}
3130

3231
return &App{
33-
DB: db,
34-
Echo: echo.New(),
35-
Log: zerolog.NewZeroLog(ctx, os.Stdout),
36-
Cfg: cfg,
32+
db: db,
33+
echo: echo.New(),
34+
log: zerolog.NewZeroLog(ctx, os.Stdout),
35+
cfg: cfg,
3736
}
3837
}
3938

4039
func (app *App) Start() error {
4140
if err := app.StartService(); err != nil {
42-
app.Log.Z().Err(err).Msg("[app]StartService")
41+
app.log.Z().Err(err).Msg("[app]StartService")
4342

4443
return err
4544
}
4645

47-
app.Echo.Debug = app.Cfg.Server.Debug
48-
app.Echo.Use(middleware.AppCors())
49-
app.Echo.Use(middleware.CacheWithRevalidation)
46+
app.echo.Debug = app.cfg.Server.Debug
47+
app.echo.Use(middleware.AppCors())
48+
app.echo.Use(middleware.CacheWithRevalidation)
5049

51-
return app.Echo.StartServer(&http.Server{
52-
Addr: fmt.Sprintf(":%s", app.Cfg.Server.RESTPort),
53-
ReadTimeout: app.Cfg.Server.ReadTimeout,
54-
WriteTimeout: app.Cfg.Server.WriteTimeout,
55-
})
50+
return app.echo.Start(fmt.Sprintf(":%s", app.cfg.Server.RESTPort))
5651
}

internal/app/service.go

+5-10
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,13 @@ import (
77
)
88

99
func (app *App) StartService() error {
10-
// define repository
11-
userRepo := userRepository.NewRepository(app.DB, app.Log)
10+
userRepo := userRepository.NewRepository(app.db)
11+
userUC := userUseCase.NewUseCase(userRepo, app.cfg)
12+
userCTRL := userV1.NewHandlers(userUC)
1213

13-
// define usecase
14-
userUC := userUseCase.NewUseCase(userRepo, app.Log, app.Cfg)
14+
domain := app.echo.Group("/api/v1/users")
1515

16-
// define controllers
17-
userCTRL := userV1.NewHandlers(userUC, app.Log)
18-
19-
version := app.Echo.Group("/api/v1/")
20-
21-
userV1.UserPrivateRoute(version, userCTRL, app.Cfg)
16+
userCTRL.UserRoutes(domain, app.cfg)
2217

2318
return nil
2419
}

internal/users/delivery/http/v1/handler.go

+6-31
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,19 @@ import (
55
"net/http"
66
"time"
77

8+
"github.com/DoWithLogic/golang-clean-architecture/internal/users"
89
"github.com/DoWithLogic/golang-clean-architecture/internal/users/dtos"
9-
usecases "github.com/DoWithLogic/golang-clean-architecture/internal/users/usecase"
1010
"github.com/DoWithLogic/golang-clean-architecture/pkg/middleware"
11-
"github.com/DoWithLogic/golang-clean-architecture/pkg/otel/zerolog"
1211
"github.com/DoWithLogic/golang-clean-architecture/pkg/utils/response"
1312
"github.com/labstack/echo/v4"
1413
)
1514

16-
type (
17-
Handlers interface {
18-
Login(c echo.Context) error
19-
CreateUser(c echo.Context) error
20-
UserDetail(c echo.Context) error
21-
UpdateUser(c echo.Context) error
22-
UpdateUserStatus(c echo.Context) error
23-
}
24-
25-
handlers struct {
26-
uc usecases.Usecase
27-
log *zerolog.Logger
28-
}
29-
)
30-
31-
const (
32-
BooleanTextTrue = "true"
33-
BooleanTextFalse = "false"
34-
)
15+
type handlers struct {
16+
uc users.Usecase
17+
}
3518

36-
func NewHandlers(uc usecases.Usecase, log *zerolog.Logger) Handlers {
37-
return &handlers{uc, log}
19+
func NewHandlers(uc users.Usecase) *handlers {
20+
return &handlers{uc}
3821
}
3922

4023
func (h *handlers) Login(c echo.Context) error {
@@ -66,8 +49,6 @@ func (h *handlers) CreateUser(c echo.Context) error {
6649
defer cancel()
6750

6851
if err := c.Bind(&payload); err != nil {
69-
h.log.Z().Err(err).Msg("[handlers]CreateUser.Bind")
70-
7152
return c.JSON(http.StatusBadRequest, response.NewResponseError(
7253
http.StatusBadRequest,
7354
response.MsgFailed,
@@ -76,8 +57,6 @@ func (h *handlers) CreateUser(c echo.Context) error {
7657
}
7758

7859
if err := payload.Validate(); err != nil {
79-
h.log.Z().Err(err).Msg("[handlers]CreateUser.Validate")
80-
8160
return c.JSON(http.StatusBadRequest, response.NewResponseError(
8261
http.StatusBadRequest,
8362
response.MsgFailed,
@@ -120,17 +99,13 @@ func (h *handlers) UpdateUser(c echo.Context) error {
12099
defer cancel()
121100

122101
if err := c.Bind(&request); err != nil {
123-
h.log.Z().Err(err).Msg("[handlers]UpdateUser.Bind")
124-
125102
return c.JSON(http.StatusBadRequest, response.NewResponseError(http.StatusBadRequest, response.MsgFailed, err.Error()))
126103
}
127104

128105
request.UserID = identity.UserID
129106
request.UpdateBy = identity.Email
130107

131108
if err := request.Validate(); err != nil {
132-
h.log.Z().Err(err).Msg("[handlers]UpdateUser.Validate")
133-
134109
return c.JSON(http.StatusBadRequest, response.NewResponseError(http.StatusBadRequest, response.MsgFailed, err.Error()))
135110
}
136111

internal/users/delivery/http/v1/route.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import (
66
"github.com/labstack/echo/v4"
77
)
88

9-
func UserPrivateRoute(version *echo.Group, h Handlers, cfg config.Config) {
10-
users := version.Group("users")
11-
users.POST("", h.CreateUser)
12-
users.POST("/login", h.Login)
13-
users.GET("/detail", h.UserDetail, middleware.AuthorizeJWT(cfg))
14-
users.PATCH("/update", h.UpdateUser, middleware.AuthorizeJWT(cfg))
15-
users.PUT("/update/status", h.UpdateUserStatus, middleware.AuthorizeJWT(cfg))
9+
func (h *handlers) UserRoutes(domain *echo.Group, cfg config.Config) {
10+
domain.POST("", h.CreateUser)
11+
domain.POST("/login", h.Login)
12+
domain.GET("/detail", h.UserDetail, middleware.AuthorizeJWT(cfg))
13+
domain.PATCH("/update", h.UpdateUser, middleware.AuthorizeJWT(cfg))
14+
domain.PUT("/update/status", h.UpdateUserStatus, middleware.AuthorizeJWT(cfg))
1615
}

internal/users/mock/repository_mock.go

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/users/mock/usecase_mock.go

+2-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/users/repository.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package users
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
7+
"github.com/DoWithLogic/golang-clean-architecture/internal/users/entities"
8+
)
9+
10+
type Repository interface {
11+
Atomic(ctx context.Context, opt *sql.TxOptions, repo func(tx Repository) error) error
12+
13+
GetUserByID(context.Context, int64, ...entities.LockingOpt) (entities.Users, error)
14+
GetUserByEmail(context.Context, string) (entities.Users, error)
15+
SaveNewUser(context.Context, entities.Users) (int64, error)
16+
UpdateUserByID(context.Context, entities.UpdateUsers) error
17+
UpdateUserStatusByID(context.Context, entities.UpdateUserStatus) error
18+
IsUserExist(ctx context.Context, email string) bool
19+
}

internal/users/repository/repository.go

+8-34
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,27 @@ import (
44
"context"
55
"database/sql"
66

7+
"github.com/DoWithLogic/golang-clean-architecture/internal/users"
78
"github.com/DoWithLogic/golang-clean-architecture/internal/users/entities"
89
"github.com/DoWithLogic/golang-clean-architecture/internal/users/repository/repository_query"
910
"github.com/DoWithLogic/golang-clean-architecture/pkg/datasource"
10-
"github.com/DoWithLogic/golang-clean-architecture/pkg/otel/zerolog"
1111
"github.com/DoWithLogic/golang-clean-architecture/pkg/utils"
1212
"github.com/jmoiron/sqlx"
1313
)
1414

15-
type (
16-
Repository interface {
17-
Atomic(ctx context.Context, opt *sql.TxOptions, repo func(tx Repository) error) error
18-
19-
GetUserByID(context.Context, int64, ...entities.LockingOpt) (entities.Users, error)
20-
GetUserByEmail(context.Context, string) (entities.Users, error)
21-
SaveNewUser(context.Context, entities.Users) (int64, error)
22-
UpdateUserByID(context.Context, entities.UpdateUsers) error
23-
UpdateUserStatusByID(context.Context, entities.UpdateUserStatus) error
24-
IsUserExist(ctx context.Context, email string) bool
25-
}
26-
27-
repository struct {
28-
db *sqlx.DB
29-
conn datasource.ConnTx
30-
log *zerolog.Logger
31-
}
32-
)
15+
type repository struct {
16+
db *sqlx.DB
17+
conn datasource.ConnTx
18+
}
3319

34-
func NewRepository(c *sqlx.DB, l *zerolog.Logger) Repository {
35-
return &repository{conn: c, log: l, db: c}
20+
func NewRepository(c *sqlx.DB) users.Repository {
21+
return &repository{conn: c, db: c}
3622
}
3723

3824
// Atomic implements Repository Interface for transaction query
39-
func (r *repository) Atomic(ctx context.Context, opt *sql.TxOptions, repo func(tx Repository) error) error {
25+
func (r *repository) Atomic(ctx context.Context, opt *sql.TxOptions, repo func(tx users.Repository) error) error {
4026
txConn, err := r.db.BeginTxx(ctx, opt)
4127
if err != nil {
42-
r.log.Z().Err(err).Msg("[repository]Atomic.BeginTxx")
43-
4428
return err
4529
}
4630

@@ -69,8 +53,6 @@ func (repo *repository) SaveNewUser(ctx context.Context, user entities.Users) (u
6953

7054
err = new(datasource.DataSource).ExecSQL(repo.conn.ExecContext(ctx, repository_query.InsertUsers, args...)).Scan(nil, &userID)
7155
if err != nil {
72-
repo.log.Z().Err(err).Msg("[repository]SaveNewUser.ExecContext")
73-
7456
return userID, err
7557
}
7658

@@ -90,8 +72,6 @@ func (repo *repository) UpdateUserByID(ctx context.Context, user entities.Update
9072

9173
err := new(datasource.DataSource).ExecSQL(repo.conn.ExecContext(ctx, repository_query.UpdateUsers, args...)).Scan(nil, nil)
9274
if err != nil {
93-
repo.log.Z().Err(err).Msg("[repository]UpdateUserByID.ExecContext")
94-
9575
return err
9676
}
9777

@@ -123,7 +103,6 @@ func (repo *repository) GetUserByID(ctx context.Context, userID int64, options .
123103
}
124104

125105
if err = new(datasource.DataSource).QuerySQL(repo.conn.QueryxContext(ctx, query, args...)).Scan(row); err != nil {
126-
repo.log.Z().Err(err).Msg("[repository]GetUserByID.QueryxContext")
127106
return userData, err
128107
}
129108

@@ -141,8 +120,6 @@ func (repo *repository) UpdateUserStatusByID(ctx context.Context, req entities.U
141120
var updatedID int64
142121
err := new(datasource.DataSource).ExecSQL(repo.conn.ExecContext(ctx, repository_query.UpdateUserStatusByID, args...)).Scan(nil, &updatedID)
143122
if err != nil {
144-
repo.log.Z().Err(err).Msg("[repository]UpdateUserStatusByID.ExecContext")
145-
146123
return err
147124
}
148125

@@ -161,8 +138,6 @@ func (repo *repository) IsUserExist(ctx context.Context, email string) bool {
161138

162139
err := new(datasource.DataSource).QuerySQL(repo.conn.QueryxContext(ctx, repository_query.IsUserExist, args...)).Scan(row)
163140
if err != nil {
164-
repo.log.Z().Err(err).Msg("[repository]IsUserExist.QueryxContext")
165-
166141
return false
167142
}
168143

@@ -184,7 +159,6 @@ func (repo *repository) GetUserByEmail(ctx context.Context, email string) (userD
184159

185160
err = new(datasource.DataSource).QuerySQL(repo.conn.QueryxContext(ctx, repository_query.GetUserByEmail, args...)).Scan(row)
186161
if err != nil {
187-
repo.log.Z().Err(err).Msg("[repository]GetUserByID.QueryxContext")
188162
return entities.Users{}, err
189163
}
190164

internal/users/repository/repository_test.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package repository_test
22

33
import (
44
"context"
5-
"os"
65
"testing"
76
"time"
87

@@ -11,7 +10,6 @@ import (
1110
"github.com/DoWithLogic/golang-clean-architecture/internal/users/repository"
1211
"github.com/DoWithLogic/golang-clean-architecture/internal/users/repository/repository_query"
1312
"github.com/DoWithLogic/golang-clean-architecture/pkg/constant"
14-
"github.com/DoWithLogic/golang-clean-architecture/pkg/otel/zerolog"
1513
"github.com/jmoiron/sqlx"
1614
"github.com/stretchr/testify/assert"
1715
"github.com/stretchr/testify/require"
@@ -27,7 +25,7 @@ func Test_repository_UpdateUserByID(t *testing.T) {
2725

2826
var (
2927
conn = sqlx.NewDb(db, "sqlmock")
30-
repo = repository.NewRepository(conn, zerolog.NewZeroLog(context.Background(), os.Stdout))
28+
repo = repository.NewRepository(conn)
3129
)
3230

3331
currentTime := time.Now()

internal/users/usecase.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package users
2+
3+
import (
4+
"context"
5+
6+
"github.com/DoWithLogic/golang-clean-architecture/internal/users/dtos"
7+
)
8+
9+
type Usecase interface {
10+
Login(ctx context.Context, request dtos.UserLoginRequest) (response dtos.UserLoginResponse, httpCode int, err error)
11+
Create(ctx context.Context, payload dtos.CreateUserRequest) (userID int64, httpCode int, err error)
12+
PartialUpdate(ctx context.Context, data dtos.UpdateUserRequest) error
13+
UpdateStatus(ctx context.Context, req dtos.UpdateUserStatusRequest) error
14+
Detail(ctx context.Context, id int64) (detail dtos.UserDetailResponse, httpCode int, err error)
15+
}

0 commit comments

Comments
 (0)