From 31a10a56af57e3d00db321d1f82ebcc6cbd4fc25 Mon Sep 17 00:00:00 2001 From: Mehdi Hadeli Date: Fri, 19 Jan 2024 20:42:31 +0330 Subject: [PATCH] refactor: :recycle: cqrs refactoring --- internal/pkg/core/cqrs/command.go | 7 +++- internal/pkg/core/cqrs/command_test.go | 18 +++++++-- internal/pkg/core/cqrs/notification.go | 30 ++++++++++++++ internal/pkg/core/cqrs/query.go | 10 ++++- internal/pkg/core/cqrs/query_test.go | 40 +++++++++++-------- internal/pkg/core/cqrs/request.go | 22 ++++++++++ internal/pkg/core/cqrs/tx_request.go | 7 +++- .../mediator_transaction_pipeline.go | 4 +- .../creatingproduct/v1/create_product.go | 2 +- .../deletingproduct/v1/delete_product.go | 2 +- .../v1/delete_product_handler.go | 2 +- .../updatingproduct/v1/update_product.go | 2 +- .../v1/update_product_handler.go | 2 +- 13 files changed, 115 insertions(+), 33 deletions(-) create mode 100644 internal/pkg/core/cqrs/notification.go create mode 100644 internal/pkg/core/cqrs/request.go diff --git a/internal/pkg/core/cqrs/command.go b/internal/pkg/core/cqrs/command.go index a7509554..cbb90905 100644 --- a/internal/pkg/core/cqrs/command.go +++ b/internal/pkg/core/cqrs/command.go @@ -2,16 +2,21 @@ package cqrs type command struct { TypeInfo + Request } type Command interface { isCommand() + Request TypeInfo } func NewCommandByT[T any]() Command { - c := &command{TypeInfo: NewTypeInfoT[T]()} + c := &command{ + TypeInfo: NewTypeInfoT[T](), + Request: NewRequest(), + } return c } diff --git a/internal/pkg/core/cqrs/command_test.go b/internal/pkg/core/cqrs/command_test.go index 30897b8d..32cb7cf7 100644 --- a/internal/pkg/core/cqrs/command_test.go +++ b/internal/pkg/core/cqrs/command_test.go @@ -25,10 +25,20 @@ func Test_Command(t *testing.T) { assert.True(t, isImplementedCommand) var i interface{} = command - _, ok := i.(Command) - _, ok2 := i.(TypeInfo) - assert.True(t, ok) - assert.True(t, ok2) + _, isCommand := i.(Command) + _, isTypeInfo := i.(TypeInfo) + _, isQuery := i.(Query) + _, isRequest := i.(Request) + + assert.True(t, isCommand) + assert.True(t, isTypeInfo) + assert.True(t, isRequest) + assert.False(t, isQuery) + + assert.True(t, IsCommand(command)) + assert.True(t, IsRequest(command)) + assert.False(t, IsQuery(command)) + assert.Equal(t, command.ShortTypeName(), "*CreateProductTest") assert.Equal(t, command.FullTypeName(), "*cqrs.CreateProductTest") } diff --git a/internal/pkg/core/cqrs/notification.go b/internal/pkg/core/cqrs/notification.go new file mode 100644 index 00000000..974c03fa --- /dev/null +++ b/internal/pkg/core/cqrs/notification.go @@ -0,0 +1,30 @@ +package cqrs + +type notification struct { + TypeInfo +} + +type Notification interface { + isNotification() + + TypeInfo +} + +func NewNotificationByT[T any]() Notification { + n := ¬ification{ + TypeInfo: NewTypeInfoT[T](), + } + + return n +} + +func (c *notification) isNotification() { +} + +func IsNotification(obj interface{}) bool { + if _, ok := obj.(Notification); ok { + return true + } + + return false +} diff --git a/internal/pkg/core/cqrs/query.go b/internal/pkg/core/cqrs/query.go index e34d33dc..7957d848 100644 --- a/internal/pkg/core/cqrs/query.go +++ b/internal/pkg/core/cqrs/query.go @@ -2,15 +2,21 @@ package cqrs type query struct { TypeInfo + Request } type Query interface { - TypeInfo isQuery() + + Request + TypeInfo } func NewQueryByT[T any]() Query { - return &query{TypeInfo: NewTypeInfoT[T]()} + return &query{ + TypeInfo: NewTypeInfoT[T](), + Request: NewRequest(), + } } func (q *query) isQuery() { diff --git a/internal/pkg/core/cqrs/query_test.go b/internal/pkg/core/cqrs/query_test.go index d37e30c3..63120450 100644 --- a/internal/pkg/core/cqrs/query_test.go +++ b/internal/pkg/core/cqrs/query_test.go @@ -3,36 +3,42 @@ package cqrs import ( "testing" + "github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/reflection/typemapper" + uuid "github.com/satori/go.uuid" "github.com/stretchr/testify/assert" ) func Test_Query(t *testing.T) { query := &GetProductById{ - Query: NewQueryByT[GetProductById](), + Query: NewQueryByT[*GetProductById](), ProductID: uuid.NewV4(), } + isImplementedQuery := typemapper.ImplementedInterfaceT[Query](query) + assert.True(t, isImplementedQuery) + + var i interface{} = query + _, isQuery := i.(Query) + _, isTypeInfo := i.(TypeInfo) + _, isCommand := i.(Command) + _, isRequest := i.(Request) + + assert.True(t, isQuery) + assert.False(t, isCommand) + assert.True(t, isTypeInfo) + assert.True(t, isRequest) + assert.True(t, IsQuery(query)) -} + assert.False(t, IsCommand(query)) + assert.True(t, IsRequest(query)) -// -//func Test_Query_Is_Catstable_To_Command(t *testing.T) { -// var q Query = NewQuery() -// var c Command = commands.NewCommand() -// query, qok := q.(Query) -// command, cok := c.(Command) -// assert.True(t, qok) -// assert.True(t, cok) -// assert.NotNil(t, query) -// assert.NotNil(t, command) -// -// query, qok = command.(Query) -// assert.False(t, qok) -// assert.Nil(t, query) -//} + assert.Equal(t, query.ShortTypeName(), "*GetProductById") + assert.Equal(t, query.FullTypeName(), "*cqrs.GetProductById") +} type GetProductById struct { Query + ProductID uuid.UUID } diff --git a/internal/pkg/core/cqrs/request.go b/internal/pkg/core/cqrs/request.go new file mode 100644 index 00000000..bed4bdc5 --- /dev/null +++ b/internal/pkg/core/cqrs/request.go @@ -0,0 +1,22 @@ +package cqrs + +type request struct{} + +type Request interface { + isRequest() +} + +func NewRequest() Request { + return &request{} +} + +func (r *request) isRequest() { +} + +func IsRequest(obj interface{}) bool { + if _, ok := obj.(Request); ok { + return true + } + + return false +} diff --git a/internal/pkg/core/cqrs/tx_request.go b/internal/pkg/core/cqrs/tx_request.go index 86f880bb..68622321 100644 --- a/internal/pkg/core/cqrs/tx_request.go +++ b/internal/pkg/core/cqrs/tx_request.go @@ -1,6 +1,9 @@ package cqrs // https://www.mohitkhare.com/blog/go-naming-conventions/ -type ITxRequest interface { - IsTxRequest() bool + +type TxRequest interface { + Request + + isTxRequest() bool } diff --git a/internal/pkg/postgresgorm/pipelines/mediator_transaction_pipeline.go b/internal/pkg/postgresgorm/pipelines/mediator_transaction_pipeline.go index d8eb5863..3f360c05 100644 --- a/internal/pkg/postgresgorm/pipelines/mediator_transaction_pipeline.go +++ b/internal/pkg/postgresgorm/pipelines/mediator_transaction_pipeline.go @@ -34,8 +34,8 @@ func (m *mediatorTransactionPipeline) Handle( ) (interface{}, error) { requestName := typeMapper.GetSnakeTypeName(request) - txRequest, ok := request.(cqrs.ITxRequest) - if !ok || !txRequest.IsTxRequest() { + txRequest, ok := request.(cqrs.TxRequest) + if !ok || !txRequest.isTxRequest() { return next(ctx) } diff --git a/internal/services/catalogwriteservice/internal/products/features/creatingproduct/v1/create_product.go b/internal/services/catalogwriteservice/internal/products/features/creatingproduct/v1/create_product.go index f5d977ae..72258679 100644 --- a/internal/services/catalogwriteservice/internal/products/features/creatingproduct/v1/create_product.go +++ b/internal/services/catalogwriteservice/internal/products/features/creatingproduct/v1/create_product.go @@ -52,7 +52,7 @@ func NewCreateProductWithValidation( return command, err } -func (c *CreateProduct) IsTxRequest() bool { +func (c *CreateProduct) isTxRequest() bool { return true } diff --git a/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product.go b/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product.go index 5debf93b..d560852d 100644 --- a/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product.go +++ b/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product.go @@ -28,7 +28,7 @@ func NewDeleteProductWithValidation(productID uuid.UUID) (*DeleteProduct, error) } // IsTxRequest for enabling transactions on the mediatr pipeline -func (c *DeleteProduct) IsTxRequest() bool { +func (c *DeleteProduct) isTxRequest() bool { return true } diff --git a/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product_handler.go b/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product_handler.go index 840ab444..84b85cb9 100644 --- a/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product_handler.go +++ b/internal/services/catalogwriteservice/internal/products/features/deletingproduct/v1/delete_product_handler.go @@ -34,7 +34,7 @@ func (c *deleteProductHandler) RegisterHandler() error { } // IsTxRequest for enabling transactions on the mediatr pipeline -func (c *deleteProductHandler) IsTxRequest() bool { +func (c *deleteProductHandler) isTxRequest() bool { return true } diff --git a/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product.go b/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product.go index fc021d3b..256e3d66 100644 --- a/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product.go +++ b/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product.go @@ -47,7 +47,7 @@ func NewUpdateProductWithValidation( } // IsTxRequest for enabling transactions on the mediatr pipeline -func (c *UpdateProduct) IsTxRequest() bool { +func (c *UpdateProduct) isTxRequest() bool { return true } diff --git a/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product_handler.go b/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product_handler.go index 20ff42e7..cb592ebd 100644 --- a/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product_handler.go +++ b/internal/services/catalogwriteservice/internal/products/features/updatingproduct/v1/update_product_handler.go @@ -39,7 +39,7 @@ func (c *updateProductHandler) RegisterHandler() error { } // IsTxRequest for enabling transactions on the mediatr pipeline -func (c *updateProductHandler) IsTxRequest() bool { +func (c *updateProductHandler) isTxRequest() bool { return true }