Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More than one repository files? #67

Closed
NaufalHSyahputra opened this issue Sep 16, 2022 · 4 comments
Closed

More than one repository files? #67

NaufalHSyahputra opened this issue Sep 16, 2022 · 4 comments

Comments

@NaufalHSyahputra
Copy link

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

@Ajilagi
Copy link

Ajilagi commented Sep 16, 2022

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

@NaufalHSyahputra
Copy link
Author

NaufalHSyahputra commented Sep 16, 2022

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.

@Ajilagi
Copy link

Ajilagi commented Sep 16, 2022

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/

@NaufalHSyahputra
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants