I’m developing several phoenix based web apps, that share some common functions, like User’s Authentication, custom form generation and some contexts.
It’s really annoying to maintain same functionality in different apps. So i came to a realisation, that it would be best to have a separate application as a dependency, that contains all this common functions.
So the questions is, what is the best practices for sharing different functionality like:
- Controllers. For instance, my AuthController module is almost always the same in every app, but i also want to have some extensibility if needed
- Views. For instance, i have a custom form generation mechanism and need to render form components. It’s quite simple to have a SharedView when i run a single app, but what should i do to separate this into dependency?
I would really appreciate any advice. Thank you.
If your apps can live in the same umbrella app, definitely just make a different app that contains the common parts.
If not, go for your own library that you can reuse.
There really is no universally good advice – there is a lot of context involved as well: f.ex. can you get that common shared code with macros (if you have code generation involved)? Then your library could be even smaller. But in the case of Phoenix you often have to plug your own small code snippets here and there (like in
router.ex) so using a library or macros is really not that clear-and-cut.
When you create a dependency that is shared across multiple apps, you’re really just describing a package or library. It’s just something you can drop into your mix file as a dependency. So you might want to look into creating mix packages.
As for when to do this, just treat it like any other programming problem. After you duplicate it enough times, pick apart the common ground and see if you can make something that works for all cases (and future cases). That’s where the difficulty lies because there’s shortcuts or magic to make actually good abstractions, you can just go by experience.