Phoenix channels with RethinkDB atomic changefeeds seems to rival Meteor oplog processing.
I have an app in production that is built with Meteor. It’s built with Blaze, Iron Router, and the rest of the regular Meteor stack. It all works pretty well! However, once I started getting into Elixir and Phoenix I found it to be a much better development experience. I still like Meteor a lot and think its great. I just like learning new things and finding new tools for the toolbox and I think Elixir/Phoenix is an excellent tool. I don’t know of any point for point comparisons. Its one of those things where you have to try it to really understand the differences.
Can you comment on how mature the Elixir eco-system is with regards to functionality like authentication and deployment options?
The Elixir community is a lot different than the Meteor community. Meteor caters more to newer developers whereas the Elixir/Erlang community is more advanced focused. As a result, the community isn’t interested in providing accounts-password type packages for your app. There are a few authentication packages, but its still the early days and you’re better off rolling your own authentication system. Authentication in Phoenix is actually super easy to do yourself. It requires only a few lines of code. Deployment is fairly straight forward as well. There is a good guide for deploying to Heroku on the Phoenix website. If you’re interested in learning more I’d recommend spending time getting familiar with Elixir via the Programming Elixir book and then moving on to the Programming Phoenix book.
When I first began my journey into the world of Erlang/Elixir I found myself wishing that authentication was as simple as: meteor add accounts-password. However, I now prefer to write the authentication logic myself. The more I program the more I want control over the whole stack… haha. The good news is that writing your own auth logic is super simple given the functional nature of Phoenix. It’s hard to explain how much better functional programming is for web development. You just have to give it a try to see why.
I’ve seen the above mentioned quite often. JWT with a ulonglong bitvector for permissions.
Ever since @SkinnyGeek1010 mentioned Phoenix in a thread I can’t seem to stop absorbing everything about it in an very obsessive manner. I’m in awe. Elixr is going to take some getting used to after decades of OO, but will oh so worth it.
One good thing about Phoenix/Elixr is that a new youtube video or blog tutorial seems to come out almost on a daily basis. I’m looking forward to your Phoenix material. The React/Meteor authentication video tutorial you made was excellent.
@chuck i’m also getting close to releasing a way to reduce oplog pressure in large apps by using a Phoenix server to handle live queries and then it would send those to the client, which gets added to minimongo.
An upcoming experiment will use the Meteor rethink driver, Phoenix to handle Rethink live-queries and the change feed can be fed into a Meteor publication (which uses the manual plumbing to send down).
Speaking of Phoenix routing, i’m getting close to releasing a framework/library for Meteor server side routes. This is inspired by Phoenix and uses it’s functional style. This allows you to use custom auth (based on Node middleware) as well as Meteor email/pass if needed. It’s based on a production Meteor API I have running.
@jacobin this is what happens when you tinker with Elixir for a few weekends… it changes your JS for the better +1 for the Programming Elixir book!
Restful example:
const {scope, get, acceptJSON, applyMiddleware} = Restful;
const authenticateJWT = Middleware. authenticateJWT; // user module
applyMiddleware(
acceptJSON(),
authenticateJWT({except: 'post.user'}),
);
scope('/v1', () => {
resources('/users', UserController, {except: 'delete'})
resources('/comments', CommentController)
// or manually add routes
get('/items/', ItemController, 'index')
})
and the controller:
const {sendJson, putStatus} = Restful;
const {Item} from Models;
ItemController = {
debug: true, // prints params and return value
scrubParams: [...], // todo, will reject all contrl reqs based on rules
show(conn, {id}) {
// `$get` will throw and return json error if non-existent
// or `get` will return undefined if non-existent
const item = Repo.$get(Item, id);
return sendJson(conn, item);
},
create(conn, params) {
// you could use Repo.$insert to remove manualy error handling
const [status, result] = Repo.insert(params);
if (status === 'ok') {
return sendJson(conn, {data: result});
} else {
conn = putStatus(conn, 500);
return sendJson(conn, {error: result})
}
}
}
More examples here
Also @chuck @ryanswapp @tarlen @jacobin might like this draft i'm working on for trying to inspire Meteor to add some of Elixir's goodies! https://medium.com/p/322a81794f15/edit
Phoenix does have some drop in authentication but it’s mostly only useful for APIs since those can be straight forward (JWT tokens for example) but others need configuration.
The plus is if your client comes to you and wants SMS login and/or passwords replaced with SMS texts you can just say ‘ok! no problem!’. In a more closed off system (like Meteor), you’re scratching your head trying to figure out how to crack into it.
In your medium article you reminded me of something with this:
Another feature of Elixir docs is automatic example testing. It will test the example in the docblock by automatically running in your test suite!
Have you ever seen JSDoced? http://jsdocedjs.org/
It parses your JSDoc declarations for @param and @return types, and adds a runtime check (via Better.js) to make sure that your arguments and return values respect those defined in the JSDoc declaration. Since the check
package is already popular in Meteor and uses a similar principle, I think having something like JSDoced for Meteor would be really awesome.
Nice! I didn’t know they had that. I’m thinking even having them integrate JS doc directly would be nice low hanging fruit.
If you could just add in the doc block and it worked that would be amazing. I’ve tried a few times and gave up because it never seemed to work right
@SkinnyGeek1010 So you’re saying that you are working on some sort of Rest API that will work like express in Meteor ? If this is the case, then it is a very great idea, I was waiting for so long for something like that.
I mainly use Meteor for my projects but sometimes I need to have a more classic HTTP endpoint and do it the ‘‘express way’’, but I don’t necessarly want to have a separate app just for 1 or 2 features. I know there’s Picker, Simple Rest and Restivus but they are too much lean (Picker) or have too much features (Restivus).
@skini26 That’s great to hear! It will be like an express plus controllers… but with a more modern syntax. It’s also very much opt in. The core is using connect-route but it’s abstracted away so you don’t have to worry about it.
If you really boil it down it’s basically just turning the request into a pipeline and each step can transform it. For example the middleware transforms all routes. Then the controllers can produce side effects, and can transform the connection further (like a 500 code).
It’ll also support a model layer that could be used to abstract away validations and db logic. Though you could use db.insert(...)
directly in the controller too!
It’s very ‘un-magical’ in that you have to specify everything but it’s also very very clear what’s going on.
I agree, Restivus was too specific for me too. The nice part is that you could use this for a couple of web hooks and call it a day.
@jacobin I’m glad you are liking Elixir! I love it. It’s some pretty awesome technology.
Hassox as done a great job with his JWT library Guardian. I use that for API authentication. You still have to build auth logic into your app, but Guardian takes care of generating JWT’s and then checking them on incoming requests.
I hope to have some more material out soon! I was working on a couple blog posts but have been super busy… I’m in law school and I work probably 30+ hours a week so its a little hard to find the time. Hopefully I’ll be able to pump some Elixir content out soon! This weekend I’ve been working on a template for React/Phoenix apps. I think it will be super useful when it’s finished. Setting up the boilerplate for a React app is a huge pain haha.
Indeed. Elixir has evidently replaced Redis as the ‘thing I want to learn this winter.’
I’ve been trying to work through this video the past day or so. Looks like it contains a great deal of tribal knowledge on Phoenix security. Unfortunately the poor guy speaks as if he’s had just one too many lines. I really wish youtube had more variable speed settings than .5x.
Brunch or Webpack?
Webpack all the way! Brunch may be the most “simple” option (as the creators of Phoenix like to say) but I think that Webpack is currently the best option.
How did this topic change from React routers to Elixir and Phoenix?
Elixir looks like the next trendy language, just like Ruby and rails was a few years ago. I don’t need that. Why do I need something running on a completely different VM when we have google and apple and facebook all continually improving JS? And haven’t we all learned something about premature optimization? Not to mention that JS is the native language of the web and everybody knows it.
Elixir is Erlang; which is old, optimized, and battle tested for communications applications.
Thanks, that’s helpful. Someone should put that on the front page of Elixir.
Back to the router topic,
SSR: Flow router has an SSR branch that supports server side rendering (and they working this branch into 3.0 release of flow-router). And it seems like react-router also supports server-side rendering (see https://github.com/thereactivestack/kickstart-simple).
flow-router is specifically for meteor, but react-router has much more community support. And it seems there are simple hacks to convert a blaze template into a react component (see https://github.com/thereactivestack/meteor-blazetoreact).
@arunoda above wrote that flow router has reactive API, that is great selling point for meteor devs, however I’m a little skeptical of Meteor reactivity. I like things that happen in a predictable way, which is part of why I love react. I’m pretty new to meteor reactivity (tracker), but it seems to make code that’s not predictable and easy to follow. Any thoughts on this?
That would be the OP who did that. It’s his thread, he can do with it as he sees fit.
Whatsapp chose Elixir and scales effortlessly to millions of concurrent users.
The Whatsapp clone tutorial on the Meteor website will likely explode into flames circa 100 concurrent users.
https://forums.meteor.com/t/proposal-for-scaling-meteor-without-oplog-tailing/?source_topic_id=6867Elixir solves the above problem out of the box. It’s distributed and highly concurrent out of the box. It allows you to use any database you wish out of the box through Ecto. You can mix and match REST endpoints, Websockets or your own binary protocols out of the box. It’s self-healing out of the box.
It’s not just about ‘another flavor of the month vm.’ It’s about solving real world problems.
Elixir looks like the next trendy language, just like Ruby and rails was a few years ago
I agree, it’s definitely headed toward the trendy train. However, the good part is that it’s able to scale if your apps happen to get large enough. People are replacing parts of Rails for Elixir (actually that’s how Phoenix started, out of need). Also the language itself is super nice to work with.
That being said, I still think Meteor is 10x easier to build and get started but it’ll never be able to scale at that rate if it’s using Node as it’s core. Node just isn’t designed to scale easily with stateful long lived connections (whereas Erlang was designed for that on day 1).
I load tested a 2GB box on Digital Ocean without JS executing (need to find a better load tester) and I can only get 400 concurrent users before it would throw a lot of errors. 800 users was semi useable but it had hundreds of errors at that point and the CPU was busting at the seems. Perhaps at that scale it’s better to generate a static HTML page (view source content) and then serve that from a CDN (Cordova style connection).
Luckily most apps won’t ever have more than a couple thousand concurrent users and Meteor can handle that.
Anyway back to routing…
In my experience it makes unpredictable code less predictable. However, I think it’s really cool in small projects. It’s just hard to keep track of where all the auto-runs are. If they’re in Blaze templates it’s implied but outside of that it tends to make a mess in my code. If you put in in your router then you’re in for a “really good time”.
Though my experience is from Meteor 0.5 - 0.9 ish… then I started using React in larger apps (and now exclusively) so perhaps this has gotten better.
Have you tried FlowRouter 4.0 yet? I think I read something about that being in beta. Sounds super interesting. However, i’m bummed that SSR takes soo much CPU away. Luckily it supports sending just data down instead of the rendered page.
I read that, but I didn’t really understand it. What does it mean for a router to be reactive?