Do we need Phoenix at all?

architecture

#1

Yes, the title is triggering you. I know :smiley:

Other dissenting (or perhaps a better word is “skeptical”) views have been less formal. One person simply asked me: “Have you ever actually done this – in a Phoenix project ”, as if Phoenix was somehow special and changed the game so much that the normal rules of good design don’t apply.

If you recognize this quote from the days of old, then you know there is something strange about it… Perhaps a word or two that may have changed slightly :angel:


This post is a reflection on an article from Uncle Bob.
https://blog.cleancoder.com/uncle-bob/2011/11/22/Clean-Architecture.html

He defends our architectures should focus on 3 things:

  1. Boundaries(deal with the outside horrible world)
  2. Entities (business logic)
  3. Interactors (pass information between 1 and 2)

Now, this would make your Application logic. But you may be thinking: “Your app seems to suffer from a distinct lack of … everything else”.

Indeed I don’t mention databses, UIs, web controllers, sockets … nothing. According to the article, these are just annoying details - frameworks are annoying details, Phoenix is an annoying detail.

The article defends that you know you have a good architecture when the framework you use in your app can just be like any other plug in, that you can add and remove and update at will.

This concept is really interesting but I have never seen in my life an application following it. So I have some questions:

  1. How does the Elixir community feels about this? Agree, disagree …
  2. Are there any examples of an app using this structure?

#2

Answering the question:

No

We do not need Phoenix, at all. It is just convenience library that you should treat as implementation detail, and that is what new directory structure in Phoenix 1.4 (or 1.3 I cannot remember) does - separate application from one of its interfaces.

Of course I am yet to see any project that decides one day that they do not need the framework X and replace it all with framework Y, but that is not the point, the point is that you can do it, not that it is feasible to do. If the project is tightly coupled with everything you cannot replace framework without rewriting all of the application, if there is distinct separation then you can. Think of it like “breaking” cryptographic algorithms, we have key-recovery attack on AES which is faster than brute force by factor of ~4, which mean that you need 2254.6 operations, which mean that it is possible, just infeasible.

But returning to Phoenix applications, I have written Imager which I still treat as a best piece of the software I have written so far. I can easily replace any part of it (some parts are configurable at the time of the speaking) and to be honest I have replaced some parts of it already (replaced Porcelain with erlexec) almost without touching any other parts of the application.


TL;DR

Do we need the Phoenix? No we do not, but it is making some kinds of work much easier and simpler.


#3

This is interesting as Phoenix is making a hell of an effort that you don’t couple yourself to it. Basically the whole idea behind contexts in phoenix, which was introduced in 1.3, is trying to make you not couple your application logic to the web layer (which is essentially what phoenix does). There’s no mention of phoenix anywhere in generated context files. You could remove the whole myapp_web folder and anything left would still work. Put a plain plug based web layer in front and you’ve essentially “switched frameworks”.


#4

That’s kind of what happens in Dave Thomas’s Empex 2018 Keynote

This post is a reflection on an article from Uncle Bob.

I’d say it’s more about some of the “sequels” to that article:

Before you commit to a framework, make sure you could write it.

Phoenix is an (application) framework and the issue is around the perils of framework use in general (not Phoenix in particular).

To a large extent frameworks revolve around “commonality/variability” - the framework provides you with the commonality so you don’t have to create it (over and over again) and you can just focus and implement the parts that vary.

So as such it should be obvious that your framework defines and sets in stone that part of the architecture (or lack of it) that it is providing the commonality for (many people assume “application framework” when they hear “framework” but there are “view frameworks”, “persistence frameworks” etc. So when people claim that React isn’t a framework because it isn’t an “application framework”, I counter that it is a “view framework”.)

Frameworks are supposed to make you more productive when you create a certain type of thing that the framework is representative of (to some degree they also make individual developers more fungible). But there is a lot that can go wrong.

  • Some frameworks may not provide enough commonality to be worthwhile

  • Some frameworks apply to only a very narrow set of use cases, defeating the productivity gain ROI of learning it.

  • Some frameworks try to cover too broad a set of use cases, creating complexity that isn’t warranted for the projects they are being used for.

  • How are you going to pick the right framework for your particular problem? The most common outcome is that the “standard one” is chosen - which could simply be a “golden hammer”. So framework’s can be used in situations where they are an ill fit and consequently aren’t carrying their weight, overcomplicating things.

  • Given that framework use is often about “productivity” there is little incentive to invest in keeping your “application logic” separate - it’s more about getting something functional out of the door ASAP.

And from a developer skill building perspective frameworks can be dangerous.

  • Seems some people are perfectly happy remaining “framework users” (or library users for that matter) - i.e. they acquire the bare minimum of skill use the framework but never get to the point of understanding why it is structured the way it is. So when the next framework comes along they start from zero, never being able to recognize which parts of the framework their solutions are actually benefitting from, much less being able to recognize what kind of framework would be ideal for their particular problem space and build that instead.

So using Phoenix is a choice. But ultimately any choice has to fit the problem and the tradeoffs between the benefits gained and constraints accepted have to make sense. For example Phoenix is built around Plug and there are some use cases where Plug’s tradeoffs aren’t acceptable - which is why Raxx was created.

Then how you use Phoenix is also a choice. Accepting “Phoenix as your Architecture” may give you a short time-to-initial-success but that may create some pain in the future (which is only relevant if the project has a future - before being replaced). But there are other ways to use it to keep it from “being your application” and “defining your architecture” but optimal decoupling requires some work up front.


#5

The very concept is embodied in the oft-repeated statement that Phoenix Is Not Your Application.

Creating a Phoenix project in Phoenix 1.3 gives you a directory structure with separate “your_app” and “your_app_web” folder structures. Your Entities go in “your_app”, your Boundaries go in “your_app_web” and Phoenix suggests you put your Interactors in “contexts”.

If you want to know how well the Elixir community agrees or disagrees (well… that subset of the Elixir community that uses Phoenix) then look on this forum for the discussions surrounding Contexts. Some folks like them, some folks think they are an unnecessary complication (particularly for small projects or for folks that are just learning). Other opinions abound.


#6

@Fl4m3Ph03n1x , for someone so new to the community, you certainly do seem to relish clickbait-y controversies. I would suggest a more irenic approach.

Note that linked talk above was given in 2016, by @lance a longtime community member and also the author of Functional Web Development with Elixir, OTP, and Phoenix. He’s clearly spent considerable time thinking through these issues.

My own summary answer to your query is
a) no, your application does not need Phoenix, but
b) yes, The Elixir Community does need Phoenix.


#7

If you want to make your life easier, I would say…

Yes :003:

The beauty of Phoenix (and Elixir) is that you can build apps in a variety of ways:

  1. Use Phoenix as a monolith - great for quick prototyping and most similar to frameworks like Rails
  2. Use Phoenix with Contexts - the default and the middle ground, you kind of get the best of all worlds balanced with ease and agility
  3. Use Phoenix as a layer (or in multiple layers!) of an Umbrella or RCA Elixir app (such as PragDave’s methods)

I would use (1) for quick n dirty apps I need to get up quickly, (2) for most apps, (3) for the biggest apps.

I also agree with Greg, we generally aim to have sincere discussions here, provocative or sensationalist type openings are really not needed to get a response - most people here are happy to help and eager to share opinions :023:


#8

Thanks @gregvaughn and @easco for the shoutouts!. :slight_smile:

I personally prefer to think of Phoenix as a tool for building web interfaces rather than web applications. I try to avoid the term “Phoenix application” as well because I think it limits how we think about our approach.

In my book, that Greg alluded to, we build a fully functional application without Phoenix. That’s the first two thirds of the book.

Only when we want to make that application available on the web do we layer on a Phoenix interface. We keep the code for those two parts physically separate by means of a poncho project, as much to help the flow of the book as anything. That’s the last third of the book.

My quick response to the question:

You can definitely build a complete application without Phoenix. (I think doing so brings some strong benefits.) If you need for it to have a web interface, though, Phoenix is a fantastic choice.


Does using alias improve runtime speed on structs?
#9

This goes to the essence of the question. In all honesty, for some projects a quick and dirty monolith will do the job. I confess to having done this - and it worked a treat. Sometimes there isn’t time or budget for anything else. For these projects you really do need Phoenix. You need it because by default it incorporates the knowledge of experienced software developers who have taken care of things which in haste it is easy to overlook.

That said, I much prefer the approach laid out in PragDave’s course and the Lance Halvorsen book cited elsewhere in this thread by @gregvaughn. Incidentally, I don’t think that the Halvorsen book gets the attention that it deserves. It engaging, well written and easy to follow with a lot of wisdom compressed into a relatively small number of pages (so you can reread it) - and the code works.
While we’re on the subject of attention, @peerreynders mentioned Raxx/Ace which is also worth a look. At the very least, Raxx can highlight things about Phoenix which might not otherwise be apparent (well, it did for me anyway).


#10

Thanks @datadrover for the kind words about the book!

If anyone is interested after that mini-review, you can find it on the prag prog site.


#11

For me the rule whether to use web framework or not are:

  • Does it make you (and your team) to be more productive in writing good web app?

The case for Rails, Laravel or Phoenix, yes they do. Why? They provide useful conventions. I know there are plenty of people who talk trash about monolith apps, but if you do it correctly, a healty monolith app is way better than healthy microservices.


#12

The claim that monoliths are always better than microservices probably would not withstand close scrutiny. As the Simon and Garfunkel eulogy to Frank Lloyd Wright might have gone if Art had studied Computer Science: Software architectures may come and software architectures may go and never change your point of view. Nevertheless there are enduring principles of good software design: modularity, loose coupling and functional programming. I would suggest that the sources cited in this thread are about application of these principles rather than microservices per se. Erlang and the OTP, if not Elixir and Phoenix, were around long before microservices became fashionable. And all four will no doubt see out numerous future architectural trends.


#13

Ahh, to be honest I was not expecting this answer at all. It does make total sense to me and I think it pretty much sums up this discussion.

First of all, thank you for your POV once again. Your posts are gold mines, which I cherish.
Now, I have seen this problem so many times. You would be surprised about all the discussions I had with people telling me I should teach my Juniors jQuery before teaching them JavaScript. If you think this approach is fine (teaching library or framework X before the language they use) then… I will agree to disagree with you :smiley:

Story of my life

All my life I have used libraries and frameworks as an integral part of my apps. This means tight coupling. My seniors and everyone I knew always gave me directions to do so.

  • Building an app in PHP? You better use that framework X and build your app around it.
  • Doing feature Y? Just got o NPM and check for a module that does it so you can install it directly into your app.
  • Are you making a MEAN app? Well, think about how you can use Angular and then make your app based on it.

By now some of you may be having heart attacks, but this was how I was taught to do software development in the industry. Needless to say, that once I started reading about lose coupling, functional programming and later on the actor model I didn’t do that well.

In more than one occasion I had a boss fighting with me because I was thinking on how to make a app decoupled and scalable instead of coding in Angular (or insert framework X here) first.

So, when I read Uncle Bob’s article, I knew right on it made sense to me. But I also knew that simply asking this very same question was going to trigger some people. Or so I thought.

I never imagined, in my wildest dreams, to see a community agree that one of the major frameworks in the language is not the holy grail of salvation. I expected people to defend Phoenix with their teeth.

Which is why I addressed this expectation at the very beginning of my post. For those of you know know me, you will find a pattern quite common in my posts where I tend to diffuse tense situations via humour, like I tried here. It doesn’t always work and I am not saying it is always the best approach, but when talking about topics I see as being polemic (such as, do we really need framework X) I find humour to be a good tool (even if poorly used by me).

Needless to say, I am really surprised by the level of maturity int he community. It’s like everyone here has read the Clean Code blog or at least knows who uncle Bob is, which is something I never found in any other community.


Thank you everyone for all your replies. I don’t have time to reply to everyone but I am grateful for all your quality content.

Truth is, now I am thinking about buying @lance 's book and investigating Phoenix :smiley:


#14

I’m not exactly sure how I could have left you with that impression. I value knowledge and skill in relation to it’s half-life. Framework skills have a pretty short half-life, usually much shorter than the language it’s written in (knowing how to build an application or feature specific framework is more useful).

Personally I often resent the opportunity cost that learning a batteries-included framework imposes because sometimes the details it tries to protect me from would actually be helpful in creating a better mental model of what is actually going on.

The advice to use a framework usually comes from a “productivity” perspective - i.e. don’t get delayed by re-inventing the wheel (incorrectly). However using frameworks also move software development from a problem solving/design activity more towards a manufacturing activity.

And then there are times where: Productive is a massive red herring

As to my attitude towards jQuery - here.


#15

You didn’t left me with that impression. I just felt that your post provided a good excuse to share some personal war stories of mine and the point of my reply was to simply say one thing: I completely agree with everything you said. :smiley:


#16

If a project is at any point going to be worked on by people other that yourself, I would argue that something like phoenix is actually quite important. It allows someone to come into something already familiar with the basics. Unless you’re prepared to create documentation for your vision of how something should be structured at the level that phoenix or other frameworks are - it seems silly to go any other way.


#17

Agree with this. Yes, the community needs phoenix. I feel every community needs a web framework. Phoenix falls into the work smarter not harder category. I would seriously question an individual who would choose to roll their own over using phoenix for a web project. Swift community has been “deciding” on a web framework for a while. Rust has https://www.arewewebyet.org/. In the last 5 years I have never worked on a single project that didn’t deal with the web. I came to elixir through phoenix. Chis stepped up and hit it out of the park for the elixir community with phoenix. I go to the local meetup and I praise elixir/phoenix. I tell beginners (and whoever else will listen) they should adopt elixir and phoenix. They come here and see some clickbait questioning a large piece of the elixir adoption story. I’m not a fan of it.


#18

Glad to hear that you’re interested in the book @Fl4m3Ph03n1x! If you do decide to buy it, please let us know what you think. :slightly_smiling_face:


#19

Using a framework is not an excuse for not having a software architecture done right. There are few books that get that pretty straight.


#20

I would seriously question an individual who always used Phoenix for a web project, since many simple projects do not need it (I have several). But I do agree that for a project with many different needs (templating, API, DB, channels) Phoenix is very useful as it provides all that out of the box and a structure to follow.