#Best Practices for Cross-Module Use-Case-Specific Logic

7 messages · Page 1 of 1 (latest)

obsidian spoke
#

I have modules per resource. Some resources are related (one-to-many, one-to-one).

For example, creating resource A also requires creating multiple B’s and validating C. This means I end up touching 3 different modules’ databases.

My question:

  • In Module A, should I directly access B and C’s database for this use case?
  • Or should I add dedicated methods in B and C just for this A-specific use case, even if they’ll never be used elsewhere?
native stag
teal trench
#

Thanks for the plug @native stag. Unfortunately, my article doesn't go into workflow, which is what I believe MrSharp's challenge is now.

But, you can and probably should create a specialized service that orchestrates the work between the modules doing the work. I didn't say that so directly in the other thread, but putting the problem as you have here changed my mind. A saga-like pattern is probably the best solution.

#

To answer the questions:

In Module A, should I directly access B and C’s database for this use case?

No, each module's services should be as database self-sufficient as possible. If you wish to orchestrate work, create a specialized service to coordinate/ orchestrate between the services that do the specialized work for the process in question.

Or should I add dedicated methods in B and C just for this A-specific use case, even if they’ll never be used elsewhere?

Sometimes you have to have specialized methods in services, if the business requirements are so designed. The importance isn't code reuse, but rather how often the process step will be carried out. If the process will only be done once in the life time of the app, that would be silly and I'd question the process. But, if the process will be done many, many timed, that is then value, so it is fine to be so specialized.

If you could be more specific and describe the use case as it really is, maybe we can find even better paths to a solution or at least change your mind about what is right and wrong.

obsidian spoke
#

Hey @teal trench
do you have a repository where i can get to know how really the inter module communication is being done?

#

Let’s take this scenario of a blogging application.

We have three modules:

  • Blog
  • Comment
  • User

Now, comments aren’t limited to just blogs — they can also be made on user profiles and potentially other entities.

For example, I want to build an API for creating a blog comment:

POST /blog-comment
Body:
{
comment: string,
blogId: number
}

Here’s an intentionally odd feature to simulate complexity:
When a user posts a comment, it should receive a comment number, calculated as the total count of all comments across all blogs of the blog’s author, plus one.
So, if the author has two blogs with two comments each, the next comment’s number would be 2 + 2 + 1 = 5.

To implement this, I’d write a method inside the comment service. But for that, I need to query the Blog table to find the author, then get all of that author’s blogs, and finally count their comments.

This raises the question:

  • Should the comment service communicate with the Author service and Blog service, making multiple database calls?
  • Or should I query the database directly in one go, pulling in all the required tables myself?
#

in short, i want to know
shall i write my API in such a way that i group them logically like per feature, and dont group by techincal concerns like, controllers, services.

and simply create-comment, does everything it needs to do for creating comment