Testing

Why I choose Phoenix

Why I choose Phoenix

by Aaron Cruz

The video titled "Why I choose Phoenix" features Aaron Cruz's talk at RubyConfTH 2022, where he shares his transition from using Ruby and Rails to Elixir and the Phoenix framework. Throughout the presentation, Cruz discusses the reasons behind his shift and provides an insightful overview of the benefits of using Phoenix in web development.

Key Points Discussed:

  • Personal Background:

    • Aaron Cruz shares his journey starting with Ruby in 2008 after feeling discontent in his previous work with Flash. He highlights how Ruby ignited his passion for programming.
  • Exploration of Other Technologies:

    • Cruz briefly mentions experimenting with various languages but emphasizes his resurgence of joy while working with Elixir and Phoenix, particularly due to their functional programming nature.
  • Reasons for Choosing Phoenix:

    1. Parallel Design: Phoenix is designed for parallel processing, taking advantage of modern multi-core architectures.
    2. Speed: It offers high performance out of the box, processing requests in nanoseconds.
    3. Testing: Phoenix provides excellent testing tools that make it easy to run tests for applications efficiently.
    4. Phoenix Dashboard: The default dashboard offers real-time monitoring, tracking several useful metrics for applications.
    5. Rails-Like Generators: Maintaining familiarity, Phoenix has generators similar to Rails, aiding rapid development.
    6. Built-in Authentication: It comes with a robust authentication solution, easing user management and security.
    7. Channels for WebSockets: Phoenix simplifies WebSocket management, allowing easy real-time communication.
    8. Live View: This groundbreaking feature enables rendering and handling of HTML dynamically without extensive JavaScript.
    9. Livebook: A tool for interactive code execution and documentation that connects to running instances, enhancing developer experience.

Significant Examples:

  • Cruz references an app he developed in Phoenix that was well-received on the App Store, illustrating the framework's capability to handle traffic smoothly.

Conclusion:

Aaron concludes with encouragement for developers to explore different stacks like Phoenix, highlighting the joy and efficiency it brings to development. He invites the audience to reach out for more discussion on Phoenix and Elixir, showcasing his openness to further dialogue on the subject. The talk reaffirms the importance of finding the right tools for individual projects, promoting curiosity in the ever-evolving tech landscape.

00:00:15.139 Hello everyone! It's great to be here. I've always wanted to come to Thailand.
00:00:20.580 To Bangkok, to eat as much as humanly possible, and I've started doing that.
00:00:27.300 It's been really wonderful. I started with Ruby back in 2008, so it's been over a decade that I've been writing Rails apps and doing Ruby.
00:00:34.320 I came from a world that wasn't great, specifically working on Flash banner ads.
00:00:39.960 When you're building something that everyone loves on the internet, it gives you a warm feeling inside.
00:00:45.300 That's part of where I started with ActionScript 3, which is very similar to Java.
00:00:52.260 I got to a point where I thought, my life shouldn't be this painful. Why do I hate working?
00:00:58.680 I looked for other technologies, and what I found were these two options.
00:01:06.060 It was very hard to decide which of the two things that looked good I should pick.
00:01:11.520 So, I asked a woman named Amy Hoy, who does a lot of marketing stuff and had her own SaaS for time tracking.
00:01:17.040 At the time, I think it was called Freckle. I asked her what I should pick, and she said, 'Ruby! It's easy, just go with Ruby.'
00:01:22.380 I like to give important decisions in my life to other people, so I was like, 'Okay, I'll pick Ruby.'
00:01:28.380 I went with it, and it was really the first programming language, the first stack, that made me feel good.
00:01:36.299 I enjoyed doing side projects, and I even liked working on some of the boring stuff.
00:01:42.900 I didn't think it was possible, but it was, and I felt that feeling for about 11 years.
00:01:48.000 I've used a lot of tools in between; I did Swift for a year, Go partially, and Python for a year not too long ago.
00:01:54.960 All of it really just felt like tools to me. It's good not to get super emotionally attached to your tools.
00:02:05.700 However, Elixir and Phoenix are the first stack I've used that again gave me that joy from my work day-to-day.
00:02:12.300 With side projects, I've been able to create in a new way which feels refreshing.
00:02:18.660 The functional nature and how everything is put together forces you, with constraints, to think about your problems differently.
00:02:25.379 And the way I think about them differently is in a very positive way.
00:02:31.620 I don't know how long I've been doing Elixir development, probably off and on for about six years.
00:02:38.280 But definitely in the last two years, for any new projects I create, I start with 'mix phx.new' instead of 'rails new'.
00:02:44.640 So, thank you for the joy you brought me for 11, 12, or 10 years; I don't know how long it’s been.
00:02:51.480 I've spent enough time with Ruby that I'm comfortable enough to move on to a different stack.
00:02:57.420 I don't want you to think this is going to be any kind of Ruby-bashing talk at all.
00:03:04.099 I still appreciate Ruby, and I still use it sometimes.
00:03:09.900 I actually just wrote my first Elixir script the other day, which was one of the last holdouts I had from Ruby.
00:03:15.659 If I needed to do something quickly on the shell, I would use Ruby.
00:03:22.860 I'm almost completely done using Ruby, but I love the community and everything it has brought me over the years.
00:03:31.080 All I have to say is, there are other options out there that you might want to explore to solve different problems.
00:03:37.139 Here are ten reasons why I generally choose Phoenix before I would choose any other stack at this point.
00:03:42.600 Reason one is that everything is designed to be parallel.
00:03:47.699 There’s Moore’s law, and computers aren't really going to get faster anymore.
00:03:53.160 The megahertz aren't going to increase, but we're going to have 10 billion cores in our computers.
00:03:59.610 So everything needs to go parallel, and it's essential to think in a parallel way.
00:04:05.180 It's an exaggeration, but it's necessary to have technologies that prioritize parallelism.
00:04:10.320 For example, Go has channels, while Elixir has its processes.
00:04:17.460 Everything you use in Elixir is within a process. Your shell runs in a process, your repo runs in a process.
00:04:23.580 All of the components in Phoenix are running in processes.
00:04:31.139 When you start working in a parallel environment, it helps overcome the challenges of using threads or forking out processes.
00:04:39.360 You can create millions of processes if you want, and they take up very little memory to start.
00:04:48.000 They own their memory space, and errors are encapsulated within them.
00:04:53.600 If one crashes, it's just that process that crashes, not the whole system.
00:05:01.020 Unless, of course, you are using a supervision tree, which is a nice feature I'm not discussing today.
00:05:07.320 If you want to, feel free to come up to me later in the conference and ask me any Phoenix or Elixir questions.
00:05:13.080 You can start a simple process using spawn, which returns an address to that process.
00:05:18.660 The address is essentially where you send messages. All of these processors are started around you, and you get addresses to them.
00:05:25.000 You can also name them after a module to give it a permanent name.
00:05:31.680 Then you can send messages to it using its permanent name, or keep track of these PIDs.
00:05:38.460 Usually, in a process, you'll have a loop that continuously pulls messages off a mailbox.
00:05:44.480 Think of a PID like a mail address; when you send it a message, it goes into a mailbox, essentially a queue.
00:05:51.180 You can pull them off synchronously.
00:05:57.000 In a real production application, you spawn higher-level abstractions to manage processes.
00:06:02.940 You can start them in your application, using a supervisor tree, where one process looks after child processes.
00:06:09.380 If something breaks, the supervisor knows whether to restart it or alert you.
00:06:15.600 You can also use something called a task, which is another abstraction on top of processes.
00:06:22.920 Why am I discussing processes in the context of Phoenix?
00:06:28.740 One issue I've had with Rails, for example, is starting long-running processes or doing polling jobs.
00:06:37.320 I often end up starting polling jobs to retrieve information from a service several times a minute.
00:06:44.700 Pub/Sub works very well in the Elixir world.
00:06:52.680 So, if you need to fire and forget some message, you can send it to a process.
00:06:58.680 It can be processed outside of your normal synchronous application workflow.
00:07:06.120 For example, if you're sending off analytics that doesn't need to be perfect, you can fire them off to a process.
00:07:13.740 Sending emails and similar tasks are great for this.
00:07:20.520 You end up with an ecosystem of processes communicating with each other.
00:07:28.680 One runs here, another runs there, and the architecture in my mind makes more sense.
00:07:35.160 It feels like many little microservices that simplify communication.
00:07:41.820 Reason two is that Phoenix is incredibly fast right out of the box.
00:07:50.100 It's very quick, not quite Go speed, but close.
00:07:56.520 Many of my requests come in nanoseconds rather than milliseconds without any optimization.
00:08:03.000 I often run it on a Heroku dyno, so not a hefty box, and it feels very responsive.
00:08:09.480 For example, I've worked on a sports meditation app with a React Native frontend and a Phoenix backend.
00:08:15.120 It was featured multiple times on the App Store, and there was no blip in our CPU or memory usage.
00:08:22.140 The throughput was steady, even during huge traffic increases.
00:08:29.640 Reason three is that the testing story is excellent.
00:08:35.520 Out of the box, you get 'mix test,' which looks in your test directory and runs any files named appropriately.
00:08:42.120 There's tooling that allows you to use describe blocks like with RSpec.
00:08:49.200 Everything just works! Because it’s functional, it's often easier to reason about your testing workflow.
00:08:55.800 I have a productivity tip: if there's something you're procrastinating on, move it closer to you.
00:09:02.700 If you're learning an instrument or trying to write more, keep your guitar or writing tools close to eliminate friction.
00:09:09.840 There's a lot of friction with testing; I don't want to write tests because setting up the testing environment takes too long.
00:09:16.920 There is essentially one way to do it in Phoenix, and it works really well.
00:09:24.000 You can write tests incredibly quickly, including tests for web requests that are provided out of the box.
00:09:30.780 This makes testing efficient and fast, another reason people might neglect testing.
00:09:36.180 Running the entire test suite can take a long time, but the application I'm currently working on has a 30-40 minute test runtime.
00:09:44.040 This is a large Phoenix app, and it's manageable, so you reach a point where performance matters.
00:09:50.640 Now let's talk about creating some tests.
00:09:56.160 This is a simple example; if you create documentation, you can use it in structure.
00:10:02.520 With this example, if you have an IEx command in your documentation, you can write tests around it.
00:10:09.000 This structure allows you to verify that your documentation accurately represents the expected outcome.
00:10:15.300 Coverage tools come with the testing framework. You use 'mix,' the primary tool for generating and running tasks.
00:10:22.020 Running tests with a flag also gives you coverage results.
00:10:29.460 You receive an HTML report that helps you visualize where you're covered and where you're not.
00:10:35.880 So, reason four is that the Phoenix dashboard is added by default.
00:10:41.100 It provides useful metrics and real-time graphs. For example, you'll see RAM usage information.
00:10:49.380 There’s a thing called an atom in Elixir, which is similar to a symbol, and it tracks your memory usage.
00:10:56.100 Excessively created atoms can crash the Erlang VM if all memory is consumed.
00:11:03.240 You can add other metrics easily, and it’s backed by a library called Telemetry.
00:11:09.180 Telemetry is written in Erlang and is designed to work seamlessly with Elixir.
00:11:15.660 It’s usable similarly to the instrumentation used in Rails.
00:11:22.740 You can see your versioning, memory setup, and other metrics, including request logs.
00:11:29.640 You can push it onto production if you want, using your existing authentication.
00:11:36.600 This is all available for free and easily extendable.
00:11:42.120 Reason five is the conversation around Phoenix and being more Rails-like.
00:11:49.560 I've talked about this at Elixir conferences; some think it should be more Rails-like to attract more people.
00:11:57.720 Jay was saying it should be less so to facilitate a more flexible system.
00:12:05.520 With Phoenix, you separate concerns into different areas rather than merging everything into one.
00:12:11.640 You have a DWC web folder containing controllers, live views, channels, and templates.
00:12:19.080 Your domain logic goes into the app's flat namespace, where you can interact with databases, and much more.
00:12:25.680 It's a divergent approach from the Rails axiom: 'Rails is not your application,' advocating for clean architectural separation.
00:12:32.100 Reason six is that you get to keep your Rails-like generators.
00:12:39.480 HTML generation, JSON templates, model-like migrations, and channels for live views are all supported.
00:12:45.060 You can easily create your own generators using mix tasks.
00:12:50.100 Reason seven is that authentication is shipped with Phoenix.
00:12:56.820 There is a dependency called Phoenix Gen Auth.
00:13:02.520 Jose had experienced some dissatisfaction with Devise's inflexibility, which lacked adaptability.
00:13:07.620 He opted to work with generators instead of a library, making it easier to manage upgrades.
00:13:13.500 With its built-in authentication, you gain access to all relevant files allowing for easier implementation.
00:13:19.620 Reason eight discusses channels, which manage WebSockets in Phoenix effectively.
00:13:25.440 It's straightforward to set up and is based on core utilities in Elixir and Erlang.
00:13:31.020 You just create a socket and send tokens if necessary, which get pushed into the channel.
00:13:36.600 When you join, the channel requires you to implement a join function; events through the WebSocket go through handle functions.
00:13:44.040 You may see error messages when working with this interface, communicating through processes running continuously.
00:13:50.460 As you progress, you'll naturally dive deeper into how these Elixir patterns operate.
00:13:57.180 These channels have clients in various programming languages; I've used the Swift and JavaScript clients.
00:14:04.620 You can easily use Phoenix as your WebSocket API and integrate it with your existing applications.
00:14:11.460 Live view is groundbreaking, allowing you to render HTML and handle requests on the client side without much JavaScript.
00:14:19.440 You can increase interactivity, creating responsive interfaces without the overhead of a traditional framework.
00:14:26.760 The basic Javascript setup requires you to import a live socket, a very intuitive and developer-friendly process.
00:14:36.960 If you need JS interactivity, hooks allow seamless integration with your applications.
00:14:43.440 However, I find that most of the time, using React is unnecessary for simpler applications.
00:14:50.880 Typically, it's a single action, like clicking a button, which works seamlessly.
00:14:57.480 The most basic live view setup leverages sigils for creating data structures that validate HTML.
00:15:05.160 It swiftly updates whenever assigns are modified or the socket state changes.
00:15:11.460 You can connect actions through Phoenix clicks to handle dynamic updates from the client side.
00:15:18.840 To increase your thermostat's temperature, you create a button linked to the socket, enabling real-time adjustments.
00:15:25.260 The final reason, reason ten, is Livebook.
00:15:32.640 It's akin to Jupyter, with sections of markdown allowing for organized documentation.
00:15:38.760 You can run code cells, create graphs, and include API forms for interactive exploration.
00:15:46.560 You can run queries directly within Livebook, or create stand-alone Livebook components.
00:15:53.520 In relation to Phoenix, you can connect your Livebook to a running instance.
00:15:59.760 This enables live experimentation with your application and allows for broader use cases.
00:16:07.440 At my work, we utilize Livebooks for visualizing data and analytics.
00:16:14.280 They provide product teams insight into results without digging deeply into technicalities.
00:16:21.960 Upcoming improvements to documentation will link more relevant assets directly into Livebook.
00:16:28.920 It's an engaging way to present live documentation.
00:16:34.920 As seen in recent updates, interactive forms boost communication and engagement.
00:16:41.520 There’s a site that hosts Livebooks on the web, allowing immediate access for trials.
00:16:48.780 There are numerous aspects I wish to discuss, but time does not permit.
00:16:55.680 If you have more questions about Elixir or Phoenix, please feel free to approach me.
00:17:03.300 I am active on Twitter and looking to stream more on Twitch.
00:17:11.220 Thank you very much! Are there any questions? No questions?
00:17:17.600 Thank you, Aaron, for this overview of Phoenix and Elixir.