Closed NaufalHSyahputra closed 1 year ago
I have a question, should I create multiple repository files to handle multiple tables?
Is the files here also mean a new struct/instance of repo likes type mysqlUserRepository struct {}
& type mysqlUserAddressRepository struct {}
or is it just a file extended from the first one?
The idea of the repository instance lies in the interface or the abstraction itself from the use-cases dependency. I think user_addresses
mean that it only contains the address of the users so it includes in the User domain. Now, how do you want to abstract the interfaces{}
? Is that possible, if there are any changes likes mysql to mongodb, or mysql to HTTP Call that affected into users
but doesn't affected into user_addresses
? If yes so you need to seggregate the interface, but if not you don't have to
Hi @Ajilagi , thanks for answering my question.
Is the files here also mean a new struct/instance of repo likes
type mysqlUserRepository struct {}
&type mysqlUserAddressRepository struct {}
or is it just a file extended from the first one?
Yes, it will have different struct, different interface (but still in domain/user.go), and different New function.
Is that possible, if there are any changes likes mysql to mongodb, or mysql to HTTP Call that affected into users but doesn't affected into user_addresses ?
It's still the same using mysql, if user_addresses will call another 3rd party app I will create a new folder inside repository folder, ex: (repository/useraddressservice/user_address_service.go)
The point I asking that is because if I combine User CRUD function and UserAddress CRUD function in one file (which is inside user_mysql_repo.go), the file will be too large because it will contains around 8 functions. But if I separate user and user_address into different file, I will have two New function that I need to call in usecase.
Yes, it will have different struct, different interface (but still in domain/user.go), and different New function.
Is there any reason to make a different interface ?
It's still the same using mysql, if user_addresses will call another 3rd party app I will create a new folder inside repository folder, ex: (repository/useraddressservice/user_address_service.go)
Really is gonna possible? user_addresses
belongs to users
, so user_addresses
mean to be coupled with user
. Normally, it should not be designed for different data source
The point of my answer is why do you need an abstraction (interfaces) if you ain't gonna need it YAGNI.
The file will be too large because it will contain around 8 functions
Nothing too small with 1 function, and nothing too large with 8 functions. It always depend on the domain/entities functionalities itself
But if I separate user and user_address into different file
Yaaa correct, if you think it's too big to be read in one file split into some smaller files, just files, that's the answer
I will have two New function that I need to call in usecase.
It's a bad idea because it's looks like user_addresses
is can be use without the users
, just like what I explain above that the user_addresses
is belongs to users
.
But maybe, If you want to keep the interface smaller you can try use the composition idea likes io.Reader io.Closer io.ReadCloser
, some suggestion below
// UserRepository implementing UserAddressRepository and it's own contract
type UserRepository interface{
UserAddressRepository
// ...
}
// UserAddressRepository contains any contract of the `user_addresses`
type UserAddressRepository interface{
// ...
}
type mysqlUserRepo struct{
}
// NewUserRepository implementing UserRepository
// so you only need to call 1 New() function
func NewUserRepository() UserRepository {
return mysqlUserRepo{}
}
"The best software design is simple and easy to understand. The next time you're starting a new project, instead of thinking, "How will I architect this system, what battle-tested patterns should I use and what formal methodology should I document it with?", think "How can I come up with the simplest possible design, in a way that's easy for anyone to understand" https://blog.pragmaticengineer.com/software-architecture-is-overrated/
But maybe, If you want to keep the interface smaller you can try use the composition idea likes io.Reader io.Closer io.ReadCloser, some suggestion below
Will try this, looks good to fix my problem. Thank for answering my question.
Hi @bxcodec , thank you for creating this arch. I have a question, should I create multiple repository files to handle multiple tables? For Example I have users and user_addresses tables, and then I create user domain to handle both user and user address. If I have separate Create, Update, Delete function between user and user address, should I create two repository files (user_mysql_repo.go and user_address_mysql_repo.go) or I just create one repository file (user_mysql_repo.go).
Thanks