dmarko484

dmarko484

Still trying to find some nice way how to decouple apps within my umbrella based application. Lets assume I have umbrella base CRM/ERP like app. I have apps like:

  • customers
  • projects
  • helpdesk

Now what when project app requires the list of customers for selection box. Common approach to decouple such apps is to expose their api as microservices. But its rather too big for app that contains all the code. But I still want to make straight borders among apps internaly and don’t want apps to reference each other direcly (e.g. by calling Crm.Customers.Repo.list() from project app). I’m thinking about the internal microservice architecture, where each umbrella app would exposes its API via GenServer like process. So when project requires list of customers then project code will not call customers module directly (not calling Crm.Customers.Repo.list()) but rather ask GenServer process for list of users. GenServer message like communication seems to make nice decoupling for inter app comunication.

Using this approach each individual umbrella app would run GenServer api process that would handle inter app communication. Is this right idea or how do you suppose to handle such code decoupling? Do you see any bottlenecks for such approach ?

e.g. having  genserver: Customers.API, Projects.API - now I can send message to Customers.API process (via Registry???) with payload {:customers-list} to get list of contacts. The same way I can call {:company-save, %{ data to be saved }} to save record etc.

I this good idea?

Showing Posts 1 to 4

kelvinst

kelvinst

I like the idea, but I would be very cautious about the granularity of this services. Sometimes we tend to overengineer when it comes to microservices. Instead of doing the microservices separated by resources themselves, I would separate them by bounded contexts (thank you @peerreynders for giving me the name of the concept).

peerreynders

peerreynders

Right out of the gate we need to understand

there is a price for loose coupling: complexity. Loosely coupled distributed systems are harder to develop, maintain, and debug.

(more)

That being said loose coupling is an important aspect in designing for replace-bility.

Is the data for these applications actually stored in distinct databases? If it isn’t, you may already be in trouble from the autonomy perspective. If it is all stored in the same database it may make sense to create a separate set of queries for each application - if you have a look at diagram in the Bounded Context article you will notice that both the Sales and Support context have their own, separate Customer representation tailored to the specific needs of that context rather some singular canonical representation - because sharing of all-in-one representations can lead to coupling to irrelevant details.

Even it you decide to go the GenServer route you may want to think about Consumer Driven Contracts - i.e. have the GenServer(s) under the control of the Customer application but deploy a separate GenServer for each distinct Customer representation.

Another tactic is Command Query Responsibility Separation. I.e. if modifications to customers is permitted from outside of the Customer application the simplest implementation could offer separate GenServers for query messages and for update messages - simply to get the benefit of keeping these concerns separate.

Now I’m not saying that any of the above applies to your particular case, likely most if not all would be considered over-engineering. But it’s probably worth your time to explore these options and document why any particular option was dismissed (in many cases it is just as important to know what was considered in the past and why particular avenues were not pursued).

Spolier

https://pbs.twimg.com/media/CrMQLVYXYAETGuW.jpg

DianaOlympos

DianaOlympos

Ok so… there are so much things to say here…

  1. Loose coupling reduce complexity to me :smiley: there is a fight to do here..

  2. [quote=“dmarko484, post:1, topic:3636”]
    But I still want to make straight borders among apps internaly and don’t want apps to reference each other direcly (e.g. by calling Crm.Customers.Repo.list() from project app)
    [/quote]

Why ? Where is the problem that make you want to do things like that?

Why not have a client lib and a server lib? There are use case when you may want to not call code directly but… you lose all the advantage of functions and public API idea. The whole idea of a public API is to exactly hide these gateways.

Davidsoff

Davidsoff

my two cents:

Microservices should be decoupled in time. This means that your project should not be dependent on your CRM system to be up.

this means that you can have your Project service listen for Change Events published by the CRM system and save the relevant information in its own database

that way even if you manage to completely destroy your CRM system you will still have a fully functional Project system

other good information on the topic: Does each microservice really need its own database? | plain old objects

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews