Pergunta

I am trying to organize my architecture following the clean architecture while using some common practices/frameworks. I'm writing in PHP, but have no problem with other languages. The flow of my app is somewhat like this:

  1. I got a front controller/bootstrapper which instantiates an App object.
  2. Inside de App I've got a router, which instantiates a Controller and then it calls an Action method.
  3. Controller Action gets a Use Case object as parameter using DI and returns raw data: boolean, string, array or whatever.

My doubt is: Where should I go from here? I have to build a (Psr) Response (loading views, redirecting or whatever) and send it to browser. Where this kind of logic should reside?

Let's say I have a common User Crud: A list of users is shown on screen and there's a "Create User" Button, which links to a Create User form. If validation fails on this form, the form is shown again showing why it was rejected. If everything is OK, then the user is redirected to the "Users list" again. After I execute the Use Case on controller, should I test the return and build the Response (render views and/or call redirect to other screen or print a JSON if it's an API method) right in the Controller Action? It just seems wrong. I have read a lot of stuff about SOLID, Clean Architecture, Separation of Concerns and good practices and I truly could not find anything addressing this kind of thing.

I appreciate if someone can shed some light on my thoughts. I also apologize for this long post and for possible grammar errors, because English is not my native language.

Foi útil?

Solução

After I execute the Use Case on controller, should I test the return and build the Response(render views and/or call redirect to other screen or print a json if it's an api method) right in the Controller Action?

In Clean Architecture the Use Case doesn't return to the Controller. Take a look at this:

enter image description here

I know here Uncle Bob has named it Interactor instead of Use Case but it's the same thing.

Anyway, in Clean Architecture after the Controller calls the Use Case (or Interactor, or Application Business Rule, or whatever the hell you want to call it) the Controller is done. It wont do anything again until another request comes in.

@candied_orange. In order to build the Response, the Use Case must be aware of outer layers, which is not good. - Erick de Azevedo Lima

enter image description here

The Use Case knows about the Request Model, Entities, and it knows about the interfaces within it's own layer. Behind which might be hiding a repository abstracting a file system, or database, or your streaming service of cat videos. The Use Case can use all of these to build the Response Model (or, damnit - stick with a name, Output Data). Once it's ready it calls out to the presenter which deals with sending this out over the web, or to a console, or makes a new streaming cat video with it.

Here's a more complete diagram from his Clean Architecture book. I've animated the flow of control:

enter image description here

All of that conforms to the Clean Architecture object diagram. There are no cyclic dependencies. What knows about what is carefully controlled. Yet the flow of control is able to go everywhere it's needed.

enter image description here

The secret to making that work is right there in the lower right corner. It's parts have been renamed (again!), folded over, and flipped to make a plug in shape but that's the good old Dependency Inversion Principle:

enter image description here

That's how you can dive into lower layers and come back out without letting the lower layers know what they're talking to. Using return is not required.

Of course none of this works until you build this object graph. I go into doing that here and here.

Licenciado em: CC-BY-SA com atribuição
scroll top