bxcodec / go-clean-arch

Go (Golang) Clean Architecture based on Reading Uncle Bob's Clean Architecture
MIT License
9.06k stars 1.19k forks source link

Usage of one usecase into another #37

Open artem-malko opened 4 years ago

artem-malko commented 4 years ago

First of all, thanks for great articles. It really helps me)

As I understand, it's ok, that usecase layer can be depend on many repositories. We can see it in article_usecse.go But let's imagine, that I have users and sessions. In user we can Create and Delete users. In sessions we can Create and Delete Session. Create and Delete are methods of usecase layer in users and sessions. The problem is in Delete method. If we delete user, we also need to delete sessions. So, it means, that I need to add session usecase Delete to user usecase layer. Is it ok? It can be something like that in main.go

sessionUsecase := NewSessionUsecase(sessionRep)
userUsecase := NewSessionUsecase(userRep, sessionUsecase)

Thank you)

artem-malko commented 4 years ago

I have one Idea, how to implement it — create one more entity. Something like userSession. It can be depend on user usecase and session usecase. But it means, that user usecase won't have method Delete. And it looks quite strange)

bxcodec commented 4 years ago

Hey bro @artem-malko, sorry for the late reply, so busy lately hope you doing good.

If I understand correctly,

When Delete user called, session delete also called as well, and that goes to Creation as well? Right?

And you're confusing to import the usecase? Well, IMO, it's okay, because either it was repository or usecase, you still communicate with interface anyway. And they will still independent, you can still do testing without really tight coupled between those two.

But If I were you, I will import the session repository in User usecase, and user repository in Session usecase.

They still have different scope, but the shared the same state which is the repository.

Hopefully, this answers your question

artem-malko commented 4 years ago

@bxcodec thx for your reply)

I've added high-order entity — manager) For example, I have user manager, which includes user and session services (usecases in your terms). Only manager could start transaction, manager could use services in high-order methods like Delete)

Delete for router = delete User + delete Session. So, I have the delete-method in my manager, which starts transaction and delete user via user service and delete session for user via session service.

So, it looks like: repository (as an interface to DB) —» service (as an interface to usecase in your terms. Could include many repositories) —» manager (as main interface). So, my API can calll only one method of manager to delete any user) And it's much more easy to test it, cause in API tests I need to mock only one manager method (in case of delete testing).

So, what do you think about such architecture?)

rafi commented 3 years ago

@artem-malko sounds interesting. Can you share an example of structure and snippets?