Starting a bigger Project with Elixir and phoenix

So I have been doing a lot of cool stuff with elixir and phoenix and there is no end to the fun I am having.

Now I was thinking to up the game a bit and start building an actual large project.
Basically its a application to keep track of my day to day stuff as a lone developer.
this includes stuff like tracking tasks, a dead simple billing module , time tracking and a scheduler. in addition I am adding some of the applications I have built from before.

I am gonna develop this for fun and some practical use. I know there are applications that does all of this.

I want to be able to expand on this application in the future with maybe a simple project management system.

so I am wondering what would be the correct way of going about. I am thinking umbrella but as I read in a different post it may be a tad difficult to make data talk in between the apps.

What would you do ? and what am I not seeing ?

1 Like

Yes, an umbrella application is what you are looking for. To keep an umbrella application decoupled, try to build it as a Directed Acyclic Graph, i. e. no cyclic dependencies between its parts.

As long as you follow this rule, you can easily alter/swap the parts of the whole.

3 Likes

so If I understand DAG right , I would treat it sort of like a serial bus , picking up data from the other modules as in a “cycle” from a controller before populating the view ?

A Directed Acyclic Graph simply means: There are no mutual (in other words: cyclic) dependencies.

When subapp A needs subapp B to work, but subapp B also needs subapp A to work, then they are complected; you cannot alter one of them without touching the other.

To take a step back: The problem with umbrella applications is not that it is hard to call other parts of your code, but rather that it is easy to call other parts of your code (even when you should not), which makes it very hard to write an umbrella application that still really is an umbrella application (and not a tangled mess of things that say they are different codebases, but actually all depend on one another).

In your example, you might be able to split your application as follows:

  • A part that does the business logic of the task tracking
  • A part that does the business logic of the billing
  • A part that does the business logic of the scheduling
  • A part for each of the other apps you want to include in your application.
  • A phoenix application that wraps each of these, exposing a web interface for them.

But this is another possibility:

  • A phoenix application that does the business logic and web interface of the task tracking
  • A phoenix application that does the business logic and web interface of the billing
  • A phoenix application that does the business logic and web interface of the scheduling
  • A part for each of the other apps you want to include in your application (including web interfaces, where applicable).
  • A phoenix application that delegates to each of these, and other than that only contains a main dashboard.

Which choice is better depends on the exact scope of each of your sub-applications. And mix-and-matching these is of course also possible. And it is even possible to extract the business logic for a single component out to its own subapp, and have a web interface for that subapp as another subapp. How coarse- or fine-grained you want to go is completely up to you!

Rule of thumb: If talk between two components needs to go both directions, combine them in a single app. If talk is only one-way, then it can be split off.

9 Likes

Thank you for taking the time for this write up.

I like this way of doing things that way I could use a phoenix app for one thing and just make plain elixir modules for logic etc.

I think I want to try at the first suggestion. I could easily make some scaffolding for the UI. Then i could reuse it for embedded stuff. or if I want to integrate some with my QT applications.

Is it best to have each module handle its own database as well ? I recall this was considered best practice at from a consulting firm. But in essence it ended up in ODBC hell.

I am reading about umbrella apps now and with this in mind I am not sure who is the most excited. Me about this or kids about the presents :slight_smile:

1 Like

Sort of; A database is of course not (directly) part of your domain logic. It might be likely that for some subcomponents you want to use an SQL database, for others (D)ETS/Mnesia might be good enough (or better!), or no data needs to be stored at all.

Regardless on how you make the separation in your umbrella, separating the code that directly interacts with the database from the code performing your domain logic is usually a good idea. This is what Phoenix/Ecto try to do: Only call the Repository (i.e. the database) from your controller. (In MVC, the controller is a ‘wrapper’ around two other sub-components, the model (your domain logic and the related data structures) and the view (the user representation).

(Yes, some MVCs, notably Rails, make it really easy to break these rules and often tightly couple the model and the database. This is exactly what 'Phoenix is not your Application – it is one of your applications talks about.)

:smile:

4 Likes

My very first impression with umbrella apps was “Woah. That’s amazing, I have to build one too!”.
I love working with umbrella apps because it allows me to split my project into smaller parts which in return gives me the opportunity to maintain the applications easier and better.

My last month, or so, with Elixir and Phoenix have been full of “Woah!” and "Aha!"s… what can I say, love both of them.

1 Like

Need to look into those as well . I know they are there but not much more. personally I am partial to using the file system for saving data instead of using databases. but in the hardware world databases are overkill most of the time.

this was a good read through , I haven`t really played around with genservers much yet but will be this Christmas.

I think we had quite the similar experience. such a joy to work with elixir and its ecosystem.

2 Likes

I am currently preparing for a bigger project as well (decided not to open a new topic and just post it here). I’m planning on using @Qqwy advice of having multiple phoenix apps that each deal with a piece of business logic (such as authentication, questions and answers, notifications etc)

My question is, since I have absolutely no practical experience with umbrella apps, how do you send the data from app X to app Y? How exactly does that work?

2 Likes

I think you are confusing apps with applications. This is one of the hurdles in working with Elixir/Erlang and the BEAM. It uses a lot of terms that are overloaded in the rest of the computing world.

An Application in the OTP world is just the root of a supervision tree in the BEAM. In effect you define all the “deamons” that start up when the BEAM starts up your code. An umbrella app is really no different than using an external dependency, those also have “apps” that generally need starting at the beginning. All the umbrella stuff does is allow you to easily keep multiple applications in a single repository, rather than having to manage many repositories.

All these applications are just processes in the BEAM, you can send messages to them from any process. The trick is to keep the interfaces between applications relatively clean.

1 Like

I see.
That makes sense!

so :

  • my_app
  • admin
    • admin_web
    • admin_data
  • some_api
    • calculations
    • validation

would just mean that I can have nested umbrellas with its own configs and rules ?
Are there any cons to this way of nesting umbrellas ?