1

I'm writing a pretty common Symfony web application, in which HTML is server side rendered (it's not an SPA application).

To illustrate my question, let's take a pretty common fictional eshop application which has these bounded contexts:

  • Order
  • Product
  • ShoppingCart

Let's imagine that on the same web page must appear the following elements:

  • 5 last products added to the store
  • The current list of products the user added to the cart
  • A list of the 3 last orders the user purchased

It maybe dumb but this is a typical scenario in web pages containing many distincts areas.

So here we have, i think, three independant use cases:

  • ProductContext:GetFiveLastProductAddedToTheStoreUseCase
  • CartContext:GetUserCartUseCase
  • OrderContext:GetThreeLastOrdersUserPurchasedUseCase

In order to enfore the idea that these are three distincts use case we can imagine we need has well a CLI app which offer three distincts commands which make use of these uses cases:

    $ myapp get-five-last-products ...
    $ myapp get-user-cart ...
    $ myapp get-three-last-order ...

So in order for the presenter and the view to render the final webpage, some kind of composition has to be done somewhere. My question is where ?

I see three possibilities but i'm not sure which is the more appropriate:

  • Create a "super use case" which is calling the others uses cases and merge their responses then pass everything to the presenter which is responsible of generating the webpage. Something like: GetFiveLastProductAddedToTheStoreAndGetCartAndGetThreeLastOrdersUserPurchasedUseCase. But like this use case name sounds, it looks ugly and it seems to be strictly tailored to answer Web page composition concerns...

  • Allow the presenter to call other uses cases

    Here we could determine which one of the 3 use cases is the "main" use case of the web page (if there is any). The main use case is called from the controller. Use case then pass its response to the presenter. The presenter then make call to others uses cases to get their responses, aggregate all of this to have the required data to generate the entire webpage. It seems this solution is breaking the dependancy rules of the clean architecture because it result in a bidirectional dependency between the presenter layer and the application.

  • Make the controller calling the three uses cases, then aggregate the response and send the result to the presenter. It seems this add responsibilities to the controller and specialise it for this specific presenter.

  • Something else ?

    I could use some framework magic, like calling others controllers directly in Twig template, Symfony allow that but it couples the application to the framework ihmo and even the framework does not really recommands it for performance reasons. Or maybe some kind of another layer which would handle the composition ?

Any thoughs and advices would be really appreciated about uses cases / presenters composition in common server side rendered web environment.

I can add simple concrete chunk of code to show how i implement today a simple use case in my Symfony environment if it can help the discussion.

1 Answer 1

1

I don't think there is any rule or advice against calling multiple use cases from a presenter, multiple entities in a use case or multiple presenters in the UI etc.

You should try and follow the main rule:

The overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards

So don't have a master use case that calls other use cases. This potentially introduces problems with loops and circular references. Imagine several programmers working on their own use cases and all referencing each other.

Having the logic in a controller would be contentious. I think fat controllers are fine within reason, but if you put too much in there it begs the question of what's a use case and what's a controller.

Same with presenters, although what exactly a presenter is will depend on your framework and language.

Pushing to the UI is generally a good thing, it makes the use cases more suitable for reuse, but may require you to trust the client. Which might not be possible.

Another option is to consider whether the basic use cases you outline are maybe too simple to be use cases at all, and maybe should be in the data layer. Which would then leave room in the use case layer for more complex use cases which re use these data calls.

Lastly you shouldn't feel constricted to a set number of layers. You can add an extra layer Master-Use-Cases/Application or whatever to help you keep to the dependency direction rule without too much worrying about how to name stuff.

Just from your example I would lean towards the "move to the data layer" approach. The calls seem too basic to be use cases and it would be a simple solution to your immediate problem, you can then have 4 use cases including your master one without any cross references.

For more complex use cases with the problem, I would lean towards the UI having the composition logic. This allows for flexible UI changes.

2
  • First, thanks for your answer. Your argument make sens as the main rule is avoid circular dependency mess. I deliberatelly took a dumb simple example to avoid useless noise. So "move to the data layer" approach would be to call to repositories (or related data layer) objects directly from the uses cases if i understand correctly. Now my use cases come from differents "bounded contexts". I imagine i can"t call directly a repository from say Cart context from a use case of the ProductContext ? I suppose there must be some kind of communication channel between the contexts. Feb 21 at 14:50
  • Hmmm, not sure the DDD stuff makes sense there, but say there was an insolvable Layer/Context problem due to whatever, different teams disagreeing, I would just pop in an extra layer and let people think about it for a while. Having stuff that doesn't quite fit in the overall design is always gona pop up and I would rather have it somewhere where we know its an outlier and needs more thought, than squished into the wrong place
    – Ewan
    Feb 21 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.