That’s how I started out, as a weekend project. It ended up making me write (much) better JavaScript and completely turned my understanding of programming inside out (Elixir). I think learning Lisp would also do the same thing but for me Elixir’s syntax is so much more pragmatic. I would highly recommend Learn Elixir if you like screencasts and Dave’s Elixir book. The first 4-5 chapters are almost life changing
Phoenix does have a router for the API and HTML routes, neither are required and neither of those are realtime. It does make a pretty mean API though!
Channels are how it handles realtime (via websockets by default). These are pretty low level now and Chris has some cool things lined up for the future to add more functionality. Pairing this with RethinkDB changfeeds is really powerful stuff. These are all handled outside of the router and are authenticated once on join.
Although I did love a modularized model, view, controller design… I began moving away from it since I left Sails JS…
Phoenix uses Ecto which has a really interesting way of dealing with data. Everything in the model is a pure function and it uses changesets to validate the data and return what should go into the database. Another layer actually persists the data so the ‘model’ can be used with or without a DB to verify data consistency. It’s hard to explain but it’s very different than Mongoose and Active Record.
The controllers are very much… controllers. One nice thing is they are just functions, they take in a connection and they mutate the connection and then return the connection. By convention all side effects happen in the controller, this leaves everything else to be a pure function, which is only interesting in the debugging case and testing… pure functions are as easy to test as an add(x, y)
function.
Views are very different. They could be re-named serialization layer. With JSON they would allow you to munge or omit data to be sent to the client. with HTML they allow you to add helpers using data gathered in the controller (like blaze helpers actually). For HTML views there are ‘templates’ which take on that role.
So far i’ve only used Phoenix as an API so I haven’t used their servside HTML stuff.
Just some noob questions though, does it render React components on the server side as well?
Not that I know of. Though some Python libraries do this somehow. It seems like it would be easier to put a node server in front and have it handle that… fetching data via the Phoenix API. Personally I just bootstrap the data or serve the index page on a CDN.
Can we do GraphQL stuff?
There is GraphQL stuff available. Chris and Jose also talked about experimenting with a ‘GraphQL’ like system for Phoenix that takes the ideas from it but builds a tighter integration. (sort of like Falcor follows the same principals).
How does “real-time” data work if at first glance with the routing and all, it still uses HTTP Requests?
It doesn’t use http but here’s the gist (without a realtime db):
- Robert enters chatroom:lobby
- Joe enters chatroom
- Joe types in Hello Robert and presses send
- Joes client sends ‘new_msg’ to server with payload
- server matches a function for
'new_msg'
and it sends broadcast("msg", "chatroom:lobby", payload)
- Robert and Joe’s clients have a JS
on('msg', func...)
callback which fires and adds the message to the chat window
- All users in the lobby (both Robert and Joe) see the view refresh in real time
- Robert types in “Hello Joe” and the cycle repeats
Things to note, there is no latency compensation, this has to be added in on the frontend if wanted, Redux makes this easy. The on
callback doesn’t know how to add in the chat, it could just be some jQuery or Redux code there.
This makes for a very very simple yet very powerful system. It works across a cluster of Phoenix servers as they handle that for you.
If you’re using RethinkDB you wouldn’t have to have the server watch for a new_msg
coming in from the client, the changefeed would callback and Phoenix would broadcast it out. This makes it more simple and more reliable.