Building a best practices site for Phoenix, LiveView, Elixir, etc

Hey everyone, I often see questions regarding best practices, and examples that people can reference so they know how to structure and accomplish certain objectives they’re facing. So, I wonder if anyone is open to collaborating and creating documentation on best practices to get things done.

I’m not completely sure of the best route to doing this, but perhaps people can raise their hands to what they’re good at, and also what best practices they’d want to see be built out. Based on consensus, I can take care of the organizing, but I still feel that I’m a super newbie at Elixir despite having 1 year of experience still, so I’d have to rely on the community (you) to help with the actual knowledge part of the how to.

An example for me is showing the best practice of multi select such as fly.io’s article here but to give more detail in how to implement and update embedded schemas in a clean and reusable way. (Ecto is still a struggle for me with these things)

I think this can empower the entire community because they can have a reference on how to structure, write high-quality code, and also build confidence as an Elixir developer. The more livebeats like examples the better.

I was thinking it could be a maintainable GitHub project where people can do some PRs and then have a simple static site.

Also, I’m willing to make some youtube videos with anyone open to it, so we have both written and video documentation.

Would love everyone’s thoughts on this, and apologies if this has been discussed before.

Thanks!

12 Likes

I found out a super optimal Fibonacci sequence algorithm for Elixir:


So I was thinking, if snippets like this are collected, so we can use them in any project, just like using Emmet!


I am creating my personal project, which will be like a starter kit I can use for every other project that comes after.

I am adding all the best practices one by one, as I keep learning. I think the generators, documentations, phoenix framework generated code itself has lots of sensible defaults.

And I believe books, videos and tutorials are necessary to know why things are the way they are. Like Elixir Secure Coding Curriculum!

Plus there are tools like Dialixir, Sobelow, Credo.


Though it would be cool if we can have some default way of doing authorisation that can scale, just like Ecto library, and default Authentication generator along with an awesome Admin panel, CMS, plus anything else that Startups can use to jump start projects.

3 Likes

Would be a great addition to the community for sure!

I think the “latest and greatest” best practice is actually Chris Mccords very own LiveBeats.

4 Likes

I completely agree with this example being a best practice reference. Perhaps we can disect and document what code snippets of live beats are best practice and build some written understanding of how it works, how to implement it, etc.

Then also do that for other repos that are also considered to have best practices.

Are there any specific examples within live beats that you would consider worth mentioning for best practices?

3 Likes

I would like to read that book. :upside_down_face:

1 Like

For us beginners (with visions :sparkles: ) trying to parse out the most crucial snippets and best practices would be amazing.

i’ve tried to consume Chris’ app in my spare time but, yeah. It’s a lot to taking.

Also, a moving target etc.

I’d love to see a Phoenix Recipes book - I’ve posted about this in a few threads now:

I think it would be great if José and Chris were involved too, not necessarily as the people writing it, but as co-authors overseeing what is/isn’t included and maybe adding their thoughts on things every now and again.

It’s no longer in print, but this is what was in Rails Recipes:

Part I — Database

Recipe 1. Create Meaningful Many-to-Many Relationships 2
Recipe 2. Create Declarative Named Queries 7
Recipe 3. Connect to Multiple Databases 11
Recipe 4. Set Default Criteria for Model Operations 19
Recipe 5. Add Behavior to Active Record Associations 22
Recipe 6. Create Polymorphic Associations 26
Recipe 7. Version Your Models 31
Recipe 8. Perform Calculations on Your Model Data 36
Recipe 9. Use Active Record Outside of Rails 39
Recipe 10. Connect to Legacy Databases 41
Recipe 11. Make Dumb Data Smart with composed_of() 44
Recipe 12. DRY Up Your YAML Database Configuration File 48
Recipe 13. Use Models Safely in Migrations 50
Recipe 14. Create Self-referential Many-to-Many Relationships 52
Recipe 15. Protect Your Data from Accidental Mass Update 56
Recipe 16. Create a Custom Model Validator 58
Recipe 17. Nest has_many :through Relationships 61
Recipe 18. Keep Your Application in Sync with Your DatabaseSchema 63
Recipe 19. Seed Your Database with Starting Data 68
Recipe 20. Use Helpers in Models 70
Recipe 21. Avoid Dangling Database Dependencies 72

Part II — Controller

Recipe 22. Create Nested Resources 76
Recipe 23. Create a Custom Action in a REST Controller 80
Recipe 24. Create a Helper Method to Use in Both Controllers and Views 83
Recipe 25. Trim Your REST Resources 85
Recipe 26. Constrain Routes by Subdomain (and Other Conditions) 88
Recipe 27. Add Web Services to Your Actions 90
Recipe 28. Write Macros 94
Recipe 29. Manage a Static HTML Site with Rails 98
Recipe 30. Syndicate Your Site with RSS 100
Recipe 31. Set Your Application’s Home Page 108

Part III — User Interface

Recipe 32. Create a Custom Form Builder 112
Recipe 33. Pluralize Words on the Fly (or Not) 116
Recipe 34. Insert Action-Specific Content in a Layout 118
Recipe 35. Add Unobtrusive Ajax with jQuery 120
Recipe 36. Create One Form for Many Models 125
Recipe 37. Cache Local Data with HTML5 Data Attributes 131

Part IV — Testing

Recipe 38. Automate Tests for Your Models 136
Recipe 39. Test Your Controllers 141
Recipe 40. Test Your Helpers 145
Recipe 41. Test Your Outgoing Mailers 148
Recipe 42. Test Across Multiple Controllers 151
Recipe 43. Focus Your Tests with Mocking and Stubbing 157
Recipe 44. Extract Test Fixtures from Live Data 163
Recipe 45. Create Dynamic Test Fixtures 168
Recipe 46. Measure and Improve Your Test Coverage 172
Recipe 47. Create Test Data with Factories 176

Part V — Email

Recipe 48. Send Gracefully Degrading Rich-Content Emails 182
Recipe 49. Send Email with Attachments 185
Recipe 50. Test Incoming Email 188

Part VI — Big-Picture

Recipe 51. Roll Your Own Authentication 198
Recipe 52. Protect Your Application with Basic HTTP Authentication 203
Recipe 53. Authorize Users with Roles 206
Recipe 54. Force Your Users to Access Site Functions with SSL 211
Recipe 55. Create Secret URLs 212
Recipe 56. Use Rails Without a Database 216
Recipe 57. Create Your Own Ruby Gem 221
Recipe 58. Use Bundler Groups to Manage Per-Environment Dependencies 224
Recipe 59. Package Rake Tasks for Reuse with a Gem 226
Recipe 60. Explore Your Rails Application with the Console 228
Recipe 61. Automate Work with Your Own Rake Tasks 230
Recipe 62. Generate Documentation for Your Application 235
Recipe 63. Render Application Data as Comma-Separated Values 236
Recipe 64. Debug and Explore Your Application with the ruby-debug Gem 239
Recipe 65. Render Complex Documents as PDFs 244

Part VII — Extending Rails

Recipe 66. Support Additional Content Types with a Custom Renderer 250
Recipe 67. Accept Additional Content Types with a Custom Parameter Parser 253
Recipe 68. Templatize Your Generated Rails Applications 256
Recipe 69. Automate Recurring Code Patterns with Custom Generators 259
Recipe 70. Create a Mountable Application as a Rails EnginePlugin 266

The only issue really is Phoenix is moving pretty fast atm, so such a book might become outdated quickly (in which case a Recipes section here on the forum could be worth exploring, a bit like our ‘how would you’ type section, or adding something to the Phoenix site itself…)

14 Likes

Based on my experience with this sort of thing, any such resource (either as a book, website, repo, livebooks) has to have a full test suite that runs regular on CI, and “looks ahead” to the language’s master with unlocked deps to get ahead of changes.

Also clearly documenting the pub date and versions of software used in all code examples.

TBH this is one of my main struggles with Livebook right now; there’s no way to externally and programmatically drive its execution as a project dependency. Makes me reluctant to use them as a form of primary documentation for anything.

5 Likes

A good book format for this could be exdoc in a repo that can be versioned I would say. That way you can have doctests and even actual code sample modules referenced in the exdoc pages.

2 Likes

I imagine this can and should be handled with Git tags.

Or LiveBook nowadays, maybe.

4 Likes

@dimitarvp LiveBooks, yes please. :upside_down_face:

There’s cheatsheet feature in ExDoc, and LiveBooks can be embedded into the generated docs.

So we can read the LiveBooks when away from machines and then run it when possible.

I liked @AstonJ’s idea. I am beginner in backend dev, so I was thinking a cookbook for building SaaS related features would be great. (Not beginner algorithms and challenges, that can be its own book!)

1 Like

This is what I’m wanting to make!

Perhaps we can do an open-source book or something with these recipes.

Although I’m not sure how well this table of contents translates, so maybe we can make a group effort to make a recipe list table of contents like the one above and then flesh it out.

@AstonJ, any ideas on how you’d modify this table of contents to match Elixir?

2 Likes

I’ve started a repo here: GitHub - Morzaram/elixir-best-practices: A repo that aims to provide best practices for any task in elixir you're aiming to accomplish

I tried to see what ChatGPT could do, so if you see any inaccuracies (I know there are), I haven’t fixed them, just added some stuff and will clean and organize later. Just wanted to get repo going :slight_smile:

4 Likes
  1. Bot detection
  2. Secure Headers
  3. Authentication & Authorization best practices
  4. Monitoring, flame graphs
  5. Feature flags
  6. Realtime perf stuffs
  7. Logging with Loki
  8. Metrics with Prometheus and Grafana
  9. Image storage with MinIO and fetch with imgproxy and @kip’s image library for advance stuff.
  10. Video upload with tusd for resumable upload and ffmpeg compression and then serving appropriately.
  11. User invitation, locking, tracking how many devices they have joined from.
  12. Ways to tackle notifications and settings changes, like cross browser / tabs or cross devices.
  13. ASDF for version management and local development.
  14. Hostsfile modifications to run site in HTTPs mode in local as well. (https://derpycoder.site instead of localhost:4000)
  15. Caddy as a simple server for subdomains. (s3.derpycoder.site, img.derpycoder.site)
  16. Mkcert for cert gen in local.
  17. Meilisearch/ Typesense with LiveView for proper text search and command pallete
  18. Postgres compatible Cockroach db for scalable setup.
  19. Clustering, rolling / canary deployment.
  20. Cron job
  21. Sending email formatted with MJML
  22. Draining node before shutting down.
  23. Environment variables from .env files
  24. Creating first super user using environment variable
  25. Netdata
  26. Pgweb
  27. Varnish cache for static assets (vdo.derpycoder.site)
  28. Starting livebook directly connected to project
  29. Business intelligence using LiveBook.
  30. Credo, Sobelow
  31. Wire guard using Innernet

Etc.

4 Likes

Hey guys,

This is all the progress I have made:

I made my repo public, I have to redo it anyways for Phoenix 1.7. Also after learning 7 plus books, I might have different perspectives on doing things.


Readme is a mess, but a treasure trove for me.

Checkout the taskfile and see if you can figure out the setup.

Basically have homebrew and asdf, installations and stuff will be a breeze.

Run the hostfile related command to register domains.

Run Cockroach db, Minio, caddy and then start the server.

Start any other services and visit their respective subdomains based on caddyfile.


Please don’t create any PRs or issues as I am a complete noob.


My way of doing thing s maybe flawed, but I am overly cautious and want to avoid tech debt as much as possible and make all the right choices up front.


P.S. See seeds.exs and .env files for username and passwords.

4 Likes

Also generate certs with associated generation commands before starting, as most of the services run in HTTPs mode, even in local.

If possible I want to replace Taskfile with mix commands.

But I am not clear on how to make it slick like Taskfile.

Also how do I create a :digraph, so when I type
mix start or something, all of the underlying or necessary services start up, in a topological sorted order!


P.S. I haven’t even reached deployment related optimisations yet.

P.P.S. I hate docker, I would prefer BEAM to be the OS running and managing the whole app.

1 Like