From Node to Ruby on Rails
nikodunk.com
nikodunk.com
I eventually gave up and switched to a semi-technical product management role.
Recently I switched back to Rails after 10 years. I can't say I enjoy the whole asset pipeline business but I yearn for a simpler time and Rails gives that (to a degree).
My only wish it was simpler to host. I don't necessary want to buy into render.com or heroku.
I meant something more like "of course there's a function for that with the name you'd expect".
There's really nothing I miss about Ruby for web dev and Elixir feels like a complete win to me these days. Ruby is still far nicer for unix-y scripting, though.
I'm considering migrating to Phoenix and my biggest concern is ease of deployment
I generally use a VPS, but Render is a top-notch host if you want something managed. In many ways, I think it's like Heroku was before Salesforce bought them.
Here’s the docs for Phoenix deployments: https://render.com/docs/deploy-phoenix
A friend of mine who worked at an SEO agency once had a client who's company name was a misspelling of some noun that google would automatically fix which i found hilarious.
https://softwareengineeringdaily.com/2021/12/07/render-with-...
I would take a look at render.com. they support connected nodes and autodiscovery
Even 6 years ago when I started, you could just run it in production with `mix phx.server`, much like running `rails server` and use the exact same deployment patterns. Or you could build a release and copy it up to the server however you saw fit. At that time it was painful for some coming from different habits that involved pulling in config at run-time rather than compile time, but those patterns have also been supported since at least 2019.
Since then, the team has been continually making it easier.
Now there's a single command line to do a deploy to Fly and also one to build a docker container for you if that's what you want: https://twitter.com/chris_mccord/status/1468998944009166849
And I see nothing wrong with having the BEAM run in Docker or K8s. There's some overlap in concepts, but they work at totally different layers. Using the BEAM is like having resilient microservices _inside_ your app with none of the downsides.
I've never used Redis in any of my Elixir/Phoenix apps. In cases where I might need something like Redis to store state, I'd reach for a GenServer or maybe Mnesia instead. I've never had an issue with deployments using this strategy. Also, K8s and BEAM work together just fine using libcluster. I'm not a fan of K8s or Docker and don't use either one, but you easily can.
The benefit of BEAM is that it can surgically handle a vast array of failures without restarting the node. K8s, on the other hand, will take the pod down and restart it. In many cases, solving a problem with BEAM is like using tweezers to remove a splinter whereas K8s is more like using a sledgehammer.
People who pay for those extra boxes? Not everybody has your budget (especially when they're building things themselves, on the side, so they aren't even paid).
Scaling vertically can take you a long long way before you actually have to start separating services.
Also, higher performance translates to lower machine costs. Our server costs would easily be 4x if we ran rails. given that elixir is 80-90% as productive for writing code in the short term, its a fair deal. Over the long term, we've found elixir to be more maintainable since there's very little magic and the immutable data structures and lack of magic make it super easy to debug.
Thanks to the performance of our system, we've also managed to get by without setting up caching. (we'll probably need it eventually but our performance gains have come mostly though fine tuning our sql queries. Ecto gives us way better control over the output sql than active record or sequalize)
That said, I'm _really_ excited to get into all the goodness that Rails 7 has to offer. I really thought they lost their way with the whole webpacker debacle. I recently installed a fresh Rails 7 app and the word webpack doesn't even exist anymore! It's like a breath of fresh air to be done with that. Those were some dark days. (I'm exaggerating only a little)
This is not surprising: the Elixir folks were fairly high-visibility in the Ruby community before they did Elixir and Phoenix.
But most Rails programmers write Rails, not Ruby, and it's important to differentiate them. Ruby is a big playground. Rails is...not, by design. (This is why I do not like Rails, personally--if I am choosing to write code in Ruby, it's because I expect to need to get weird with it.)
Rails->Phoenix omits a lot of the stuff that makes Elixir cool, both in itself and in OTP, but that's not a bad thing and I do think the transfer isn't too onerous for somebody coming purely from Rails.
You're really exaggerating.
Roughly equivalent interfaces exist in Phoenix, and the mapping isn't quite 1:1 but it's close enough that the adjustment is an adjustment, I think, and not a re-learning.
I don't think we can compare languages based solely on the experience of juniors. I'm not saying it's irrelevant, it is, but it's only a part of what writing software is. In the end of the day you need the seniors and people who really get it to maintain the code and steer the ship in the right direction.
But I do agree that Rails is a kind of dialect of Ruby and that you can get pretty far with Rails without being great in Ruby (you still need to be decent though, no way of getting around that).
> Most Rails programmers I've worked with live in the controller and the view
Where is the business logic at? They also write services or something similar or stick it in the Model. Whatever isn't ActiveRecord will be pure Ruby - Rails has no opinions there.
Absolutely, and I would submit that this is most developers' experience up until a senior-ish role. Not title, you can have juniors doing this, but the pyramid of tool-users versus tool-makers.
> In the end of the day you need the seniors and people who really get it to maintain the code and steer the ship in the right direction.
Again agreed--but jeez, there are just so many fewer tool-makers at most places I've found myself. (This worked out great for me early in my career because there were tons of vacuums to start doing that work even in my first year out of college--building systems that other people could rely on to go faster, because nobody else was doing it!) Thinking about it, this impression perhaps sticks more because of the businesses I consulted for, which is perhaps where my perspective comes from--hiring uncritically 'til you're in a pit where you're paying the medium bucks to get somebody to come dig you out.
> Where is the business logic at? They also write services or something similar or stick it in the Model.
Found the guy who hasn't seen too many 10KLOC controllers in his time out there. ;)
You may be right that I am grim about this, but at the same time, reading your description makes me go "I haven't seen too many places that actually do-it-right". The truth's probably somewhere in the middle, and outliers exist on both sides. But yeah, I've absolutely been consulting for more than one company whose primary product was thin models, gargantuan controllers, and no service abstraction to speak of. They make a lot of money, too. (Fortunately for me, they brought me in for devops stuff, not "please save our megamonolith".)
I don't get why this is still happening. It's kinda common wisdom now to not let your controllers get fat. I"m not saying that fat models are great but as a community we kinda agree that most business logic stuff is easier tested on the model/service and should be placed there. CTO's/team leaders have to be real sloppy to let teams build code as you describe At the same time - being a consultant, don't you more often than not see codebases in bad state? I mean those are the ones that usually need consulting. So maybe you have an overly negative view on how Rails projects usually look.
How do you think Phoenix could better take advantage of Elixir and OTP? IMO, it already is doing plenty to take advantage of what's cool about OTP, through channels and especially LiveView. I suppose Phoenix apps could use Mnesia instead of relational databases. But would the benefits actually outweigh the costs?
I'm not following you here. Could you please explain your position a bit more?
The reason I'm confused by your commentary is that Phoenix makes extensive use of OTP and since it is just Elixir + macros, there is nothing at all limiting you from employing every Elixir (and Erlang, for that matter) feature you want to in your Phoenix apps.
At my current company, we use Phoenix and we use a lot of its bells and whistles. But we also have a lot of people who understand OTP--definitely way more than I do. I also see people ship Phoenix apps without getting deep into that when their needs are relatively small.
Of course the larger your project is, the more hassle, but that's not specific to Rails.
It is not simple. Python or Node.Js suffer the same issues, though.
Compared to dropping a go-binary or rust build somewhere and firing that up, Rails/Ruby (Rack, Sintra, Rails etc) are a mess.
In no particular order, the issues I had to deal with in the last three months:
* asset pipelines crashed randomly; turned out the ~2GB build VPS had too little memory to run the asset pipeline.
* puma and unicorn and phusion cannot be ran and configgured easily on one server.
* rbenv builds are hard to manage.
* getting the correct gems on your server is a mess. There is bundler, rbenv, vendored, rubygems.org, gem, Gemfile, Gemfile.lock, ruby-version in gemfile, ruby version .ruby-version, all of which can -and will- conflict at some point.
Add to that, that a typical Rails app requires at least redis, postgresql/mysql, quite some lib-x headers to build native gems, and imagemagick etc, and you have a very complex setup.
This isn't more complex than your typical Django, Laravel or ExpressJs setup. But it is far more complex than deploying a go, rust, or Java bundle.
I know things get simpler when you keep "one app/thread - one server". But price-wise that doesn't make sense, especially since many common Rails apps hardly run on a the cheapest VPS (a throttled dual-core 500MB server). If you run ten tiny services, ten servers add up quickly.
I also host some larger apps on their own server, some loadbalanced over multiple servers.
But throwing 10+ ruby services on a VPS is hard. Especially if you don't want to, or cannot constrain their ruby-versions, app-server, etc.
It is hard for the exact same reason why setting up a local env may be hard. I recently had to help a co-worker on an old MacOS machine who broke her entire mac-desktop because she installed RVM because somehow that was in the tutorial for getting the app locally.
Anything with a runtime is harder than anything without that runtime. This is too obvious, but does warrant some highlighting. Ruby's runtime is one of the hardest of all runtimes because it comes with so many moving parts. Python is a close second, and on Ubuntu (my main driver) probably worse than Ruby, because fing up Node is fine, but fing up Python can render your machine unusable, unrecoverable so without good understanding of all python things.
And please don't try to tell us that a real-world Java web application is simpler than, well, anything. ;-)
Tongue in cheek, but honestly, that's probably debatable.
Under the hood, Java apps (at least in my experience) are Eldritch horrors with hundreds of beans/proxies/servlets/God knows what, needless layers upon layers of abstractions and dangerous amounts of reflection and dynamic behavior, all to launch and initialize a web application in a "simple" manner. I've always seen the exact same horror, be it working with Spring Boot, Spring, JavaEE, Struts, or even something like Dropwizard (though it seemed a bit more sane). Only the microframeworks seemed decent in comparison, something like Vert.X (has a different paradigm, though), or Quarkus/Helidon.
But when it comes to running them... well, historically they were still a nightmare, if packaged with .war and relying on certain application servers/JDK versions being present. But packaging them as executable .jar files (think Spring Boot) makes them similarly easy to Go, at least as long as you have the JDK version that you need. You just drop the file in a folder and if you have some configuration (which your Go app would also need in one way or another), you can probably launch it.
> I have never had the sort of problems you say you're having trying to keep gems sorted.
Ruby suffers from the same problem that Python, Node, PHP and other non-statically compiled technologies suffer from - messing around with dependencies. If i develop on Ruby locally against version X.Y.Z, but only X.Y.W is available on the server due to Debian packaging older versions, then i'll run into problems because of the project refusing to build/run. I've also run into situations where building the native stuff (DB drivers in this case) will fail, for example, when libpq-fe.h headers were missing and pg couldn't been installed, so the gem native extension couldn't build. Also, on Windows, Ruby 2.7 downloaded the sqlite gem with 3 different trojans (Win64.Alien.eg, Win64.Alien.ef, Win32.Agent.xahigh) in the extensions (btreeinfo.dll, memstat.dll, memvfs.dll), as picked up by Kaspersky. No idea how that happened, or whether that could have been a false positive, but i didn't appreciate that much either.
That said, i have a folder that has about 112 images of all sorts of software breaking in various ways to date, and the number is only so low because i don't screenshot things on my work computer and not even every small instance of something breaking. In my experience, all of the technologies out there are bad in some ways, it's just about identifying and managing these tradeoffs towards whatever is suitable for your circumstances.
Just my 2 cents
Either you use RVM locally to develop with Ruby X.Y.W or you install RVM on the server to use Ruby X.Y.Z there. Of course if the OS on the server is too old or too new there could be some versions of Ruby that won't work. It happened to me because of versions of openssl.
That said, Docker is also oftentimes a poor option for local development, unless you're talking about external dependencies the app needs (e.g. MariaDB/PostgreSQL, RabbitMQ, Redis etc.), or maybe very specific setups that just won't be achievable otherwise (specific userland needed).
For example, when trying to run Ruby/PHP/Node/Python/Java apps in Docker containers, i've run into the following:
- problems with file permissions
- problems with file line endings
- problems with Docker Desktop bind mounts (e.g. directory won't be mounted, path parsed incorrectly etc.)
- problems with Docker Desktop bind mount performance
- problems with networking (e.g. host.docker.internal sometimes refusing to route to non-containerized stuff on the host)
- problems with run profiles (e.g. your IDE + Rails integration just won't work, at best you can just launch a different container/Compose stack with some other parameters)
- problems with test runs and coverage (if you use the IDE integration, though that depends on the stack and how deeply your IDE is integrated, e.g. Java with IntelliJ IDEA)
- problems with remote debugging, breakpoints, flame graphs etc. (most of those either don't work when the code is inside of a container, or need additional setup, e.g. remote debugging, where supported)
In my eyes, whenever possible, develop locally with the native runtimes for the IDE integration etc., use Docker for deployment or maybe QA/test environments as well - anything that will go on a server somewhere.Execjs, libreadline, libsqlite3, lib-postgres, (older)nokogiri etc. Quite a lot of the headers keep being a problem. Not major, often a mere ddg+apt-get away, but still annoying. It does get problematic when you have multiple apps depend on different libreadlines, for example.
And I'm not often deploying java, but at least the runtime and tooling has become omnipresent. The latest deploys were a mere "move all files there, and restart the service". With Rails you at least need to rebuild the gems.
Often java-services are an `apt get jenkins` away. There is no equivalent apt-get gitlab or apt-get mastodon that just sets up the stack entirely. But that is probably due to their popularity more than technology.
Some things I'd note-- * Don't use puma or unicorn. Phusion Passenger and Apache is just fine performance-wise and is much more robust IMO. * To avoid ruby version conflicts use .ruby_version as your sole source of versioning. I use this in all my Gemfiles: `ruby File.read('.ruby-version').strip` * RVM isn't as popular as rbenv but it's amazing and you won't run into the issues you mentioned. It integrates with Capistrano and Passenger+Apache really well. * 2GB might be a bit light for a production app even with light load. We start our new VMs at 8GB and then adjust up or down as makes sense.
We still do a single Ubuntu LTS VM for each app rather than anything fancy. Once you've added the stuff you need via apt it just works. Our sysops folks use Ansible playbooks that automate everything so there's no mystery when we need to do an OS upgrade or spin up a new VM.
[1]: https://github.com/havenweb/haven/tree/master/deploymentscri...
I think it can be simple if you keep it simple :). In my book Deployment from Scratch I show people how to run Rails on a cheap VPS with a couple hundreds lines of Bash.
Just Ruby + chruby + Puma + systemd (and optional systemd socket activation).
I include a scripted demo (so you don't have to do it yourself) which demonstrates all of the this:
- Setting up a git-pust deployment for Ruby applications
- Using chruby to automate installing requested Ruby versions
- Configuring NGINX as a proxy using UNIX sockets
- Setting up systemd socket activation for graceful restarts
- Configuring NGINX to serve static assets
- Configuring NGINX to proxy WebSockets connections for Action Cable
- Automatic SSL/TLS certificates with Let's Encrypt
- Redirecting HTTP traffic and subdomains to main domain over HTTPS
- Running PostgreSQL and Redis on the same server
- Building a custom SELinux module
- Configuring firewall
- Setting up automatic weekly system update
- Setting up log rotation for NGINX and PostgreSQL logs and max limit for system log
- Doing application backups and restores
- Creating admin tasks
Although it sounds like a lot, the demo is reasonably small and clean so you can go through all the files in 2 hours.
I think people many times complicate what they don't need to complicate...
> a couple hundreds lines of Bash.
One or the other. It can't be both.
And it's great!
Hatchbox takes the maintenance and setup out of DevOps for me!
Using Hatchbox makes it easier to treat servers like cattle and less like pets!
Given the popularity of rails at the time, if node.js was unproductive like you say it is, it would have never caught on.
The reality is that express was considerably simpler and easier than rails and that's what made many of the internet companies we have today even possible.
After the sit I seen with my own eyes(not internet stories) I am convinced that there are packages like "red" that defines the color RED="#ff0000" and a package colors that depends on all colors, and probably a few big dev tools that depends on the colors one, this node/npm ecosystem is crazy but we are paid to maintain and fix other people stupidity.
EDIT forgot to mention why stuff gets complex after time, you hit cases where you need to get a new version of package A , but A needs say a new node version or some new other shit, but you have a package B that will fail on the new node version with some stupid error, and package B was abandoned or the fix is to upgrade to a new major version... also you will notice that your packages are now abandoned and might have security issues when you inherit some old project , it is a big mess.
Exhibit A here is the JS language itself. It became popular not because it was the best language, just the most ubiquitous one. You could read the 25 years since as trying to turn it into a solid language.
Or look at the rise of PHP. It started out as a tool for making a Personal Home Page, which is a fine use case and was certainly a popular one in the mid/late 1990s. It eventually turned into the foundation for one of the world's largest companies. But nobody can argue it was a particularly good language. E.g. https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
Same thing with Java, really. Bunch of interesting ideas, some of which worked out and some didn't. Even at launch a lot of the things that have turned out to be problems were criticized. They say that Java is the new COBOL, and that seems pretty fair to me.
I could go on all day. The most popular technologies are not always the best. That applies to movies and music and pretty much everything. And personally, I've accepted it. It's part of how the world works. The trick for those of us who like "better" things is to figure out how to get them to become mainstream.
All the counter examples in other replies focus on one aspect of a piece of tech that was bad while completely ignoring the rest. Php might have been bad as a language but for its time, it was easier and more productive than the alternative (J2EE): the better thing won until it was supplanted by something better.
The easier deployment story for PHP3 meant you saw massive expansion at the bottom of the market as cheap webhosts were able to offer very locked-down accounts for peanuts, which meant a generation of developers came along whose only experience was with PHP. They didn't have anything to compare to and nobody was really offering them anything else at anything like the same scale. The virtualisation revolution hadn't happened yet, so these were all shared accounts on physical boxes, and they couldn't install their own stuff either.
It's just not reasonable to say PHP was "better" except in a very limited, and largely accidental sense. It just so happened that that one advantage was enough to catapult it into first place.
Never understimate the power of fad, tech pop culture, hype, and trying a shiny new thing...
It’s just me building this and I have no one in my circle that’s familiar with spring.
I guess I should be thankful re-inventing the wheel on all of these aspects in node has given me hundreds if not thousands of hours in compensation.
This video was recently linked in other thread on HN, but I feel this comment really resonates with the main conclusion: https://www.youtube.com/watch?v=pW-SOdj4Kkk
There's no need to chase the latest Node JS shenanigans. It feels like it's all we talk about on HN but a huge, huge number of developers are out there happily coding away in Java, C# and all the rest. Even within Node world the majority are using the exact same React stack (the homogeneity of which is the reason for using it in the first place).
IMO Ruby has faded because it never found its niche. Java and C# thrive in the corporate world. Python already exists as a dynamically typed server language. As much as people complain, writing server-side web stuff in JS does make sense given it's what you're using in the client. So where does Ruby go?
Same thing with Rails/Laravel/etc...people don't choose it because PHP or because Ruby , etc...the language doesn't matter at all, the tooling does matter it all.
In the web server side, helping you build web apps faster. That has been it's niche (with Rails) and it's still doing well there.
Going with the masses (e.g Java/Node/Python) is the easy thing to do. It feels "safe". But who knows where Python/Node will be 10 years from now, people are restless and will come up with new things (Deno?) and it could be they will start declining. Java is pretty much unavoidable though.
As an ML engineer it’s really hard to justify spending your time in a language you will be handicapped by instead of just using python
Well JS is forced upon us on the browser and not everyone is tremendously happy about it. It has improved, but still. Plenty of folks out there will seek other languages, we will never all fully agree on what's good on the backend.
BTW - are we positive JS will have a monopoly on browsers 5-10 years from now? (I'm talking about WebAssembly). Cos if the monopoly is gone JS will die a violent death I think.
Yes.
I will assume your question arose from the exuberance of youth.
"Good enough" + inertia = Yes
It's not enough to be better; it has to be so much better, existing infrastructure and training must become moot. And preferably an obvious best to avoid balkanization.
See: Fortune 500 and their continued reliance on COBOL and mainframes rather than opting for replacement and retraining costs.
Ruby isn't new; it's only slightly younger than Python, and brought things to the table. Rails and Django are roughly the same age (and Django started off more as a CMS). That Python exists isn't an argument against Ruby. Lots of other languages exist, each with their own cost/benefit tradeoffs.
> [...] writing server-side web stuff in JS does make sense given it's what you're using in the client.
I don't understand the argument. Matching client/server language is a different goal than matching task/language, and the task isn't the only driving factor.
There's some crossover in that the language is the same, which means you could standardize on JS developers, but the ecosystems are not the same, and the required overall skillset is different. In wee shops the tradeoff may be worth it, but at scale, the benefit is oversold.
I guess by now Rails could also be considered boring technology.
It is tiring to keep track of latest fads, specially those that don't happen to stick around, so only move when dust settles down.
Yeah one might lose business opportunities from not being first mover, on the other hand, there are business opportunities to port back the surviving projects into classical development stacks.
For me, still much better than dealing with management.
Suppose you have been given 100,000 developers to work on a website, but it will have millions of customers and things cannot fail.
Now it is actually useful to be able to parcel out the database layer to a group of 1000, and they can split up each service into groups of 100 etc.
There are enough people to decide what conventions, logging, validation people ought to use and perhaps measure them. If all of them hack on the same Rails codebase they might be running into each other all the time.
Of course, for a solo developer, it makes sense to use Rails/Django/etc.
Now there is a little spot in between 2-99,999. It is possible that there is a team or two at this level. And I think that gear shift or pathway has not yet been discovered. Typically you start on rails, suspect you should switch and then switch way too late.
A pathway might look like this:
Django -> Django API + VueJs -> Redis + update database?
It probably depends on the challenges.
If someone has an idea, or something they have tried, it would be interesting to take a look so please share.
Edited for clarity.
The vast majority of businesses/projects are small, and will only have one or a small number of developers working on it. So Ruby on Rails (or PHP or Wordpress) is a suitable choice for maybe 80% of projects.
At the same time, a very small number of businesses require 100,000+ (or even just 1000+) developers. These businesses, because they have so many developers, employ the vast majority of professional developers. Thus, maybe only 20% of professional developers work on products that are typical of business needs.
This disparity explains why communities on Hacker News are typically so negative towards Ruby on Rails. It also explains part of what makes Ruby on Rails so remarkable. Even after all these years, it has a thriving community and has resisted the pull to become more "enterprisy." It's still a tool that is targeted at and well suited for a large swath of business cases, the vast majority of which will likely never need to migrate to something "better".
We also get the benefits of a mono-repo and the benefits of microservices in the same application footprint, because every controller method is automatically deployed as its own independent lambda (this is core to how Jets works), but we're still in the usual Rails mono-repo format we all know and love. Also very strong integration between ApplicationJob and background lambdas has been killer for us.
One thing I've always said is the real difficulties in software development happen at the seams where services connect with other services. This sort of strategy (and particularly, the mono-repo format) minimizes the number of seams within your application, while still giving you the scalability and other benefits of microservices and serverless.
Is there a blog post about the tech stack? My main concern with serverless/lambda is cold start time. How do you deal with it? What does the p99 latency look like?
Also how do you scale the usual bottleneck which is the database?
More generally though, all of these "newsql" offerings feel a little too good to be true for me, I can't see how you could really have all the relational integrity of postgres with the elastic scalability of a distributed DB without trading something off. Am I too cynical?
The author addressed the cold start problem here(timestamped) https://youtu.be/a0VKbrgzKso?t=439
Hope it helps :)
From a business standpoint, that's a pretty great pitch.
Is it actually the most cost effective solution? No more so than any other tool. It depends on exactly what you're building, how, and how you measure the cost. AWS can be extremely costly, or cheap, depending on your engineering needs, constraints, and practices.
The companies I have been at where computing costs did matter were doing extremely specialized, long-running calculations that are inappropriate for lambda.
I'm sure there are rare exceptions, but this all smells like premature optimization. Developer salaries are, 9.99 times out of ten, the cost you want to optimize.
Lambda also supports Docker and is pretty damn fast now, so it's less painful to use.
Serverless as an architectural pattern is about more than just Lambda and tends to incorporate a multitude of managed services to remove the cost of managment and configuration overhead. When you use IaC tools like Serverless Framework that are built to help developers put together an application as opposed to provisioning resources, it means you can get things up fast and ready to bill you only for usage and that scales amazingly.
How do you resolve this in your projects? (Serious question).
This is such a big problem for some of the projects that they are now only able to hire senior develops (which brings it‘s own set of problems).
All of that said, I vastly prefer google cloud functions personally and would switch to that in a heartbeat if they had capabilities like API gateway but it's not there yet.
I also regret that there isn't a better cross-cloud solution currently, but that's something I have a lot of open source ambitions about creating soon. I don't like serverless that much so stay tuned for something from me in the coming years, probably in Rust.
There's not getting around the networking and such - that's the full part of full-stack (FS) - it's more than simply FE+BE. Maybe call them distributed systems engineers instead.
What it sounds like though, is your organization (regardless of what we call it) is large enough to organize into FE, BE, and FS roles, with FS running the platform and being in charge of the fleet and for them to work on the system itself so that FE and BE can work without having to know about fleet - and FS folk are building internal tools that the rest of the org use to do their job, and to shield them from any of the implementation details your fleet has.
1. You have a maximum of 30 seconds to reply to the request
2. You cannot stream data from lambda through the api gateway. Though you can stream to s3 etc.
I agree streaming needs work, but if I had to deal with that I'd probably just use naked endpoints.
If you're talking about web sockets, yeah, I feel ya. I haven't had to navigate that situation yet but my plan of action is to bypass API gateway entirely and use a naked lambda running at its full execution time, and when we approach the 15 minute boundary, send a command that resets the connection. Don't know if it would work well but I haven't had a need to use web sockets for any projects I work on for a while.
For streaming, like you said, maybe an elastic beanstalk cluster is more the way to go depending on your workflow. If you can find a way to get it all to work in Lambda though, would probably be a game changer cost-wise I would expect as long as you figure out a way to deal with resetting every 15 mins.
For reference, 90% of our bill is database related currently.
Huh. With the context of the rest of the comment, I realize (the very obvious comparison) that a database engine designed to shard to many thousands of small workers could potentially be a very attractive future development path.
Iff the current trends in cloud computing (workers, lambda, etc) continues and some other fundamental doesn't come along and overtake.
Which is probably (part of) the reason why this doesn't exist, since I think I've basically just described the P=NP of storage engineering :)
Yes. I've been patiently waiting for the database community to realize this for the last 5 years now :)
The optimal solution would of course be to shard both the compute I/O and the storage footprint, so each worker only needed to hold onto maybe 1-100MB of data.
Perhaps some existing (simpler) designs could be modified to "hyper-shard" the compute angle, but would still likely require carrying around a large percentage of the database.
In any case, you'd need an internal signalling fabric capable of (cost-effectively) handling very bursty many-to-many I/O across thousands of endpoints to make consensus work in realtime.
It would honestly be really interesting to see how something like this would work in practice.
I migrated some mid business (500-1000 people company) lambda setup to ec2 spot instances and a standard app and the costs dropped.
It would have been even cheaper on something like heztner, but good luck getting a buy-in from the infra team.
I venture most small businesses will have less load than them. Certainly it's not worth it for my tiny side businesses.
I was running some calculations for a project though, and if you "abuse" them with lengthy / expensive calculations run very infrequently (think like a cron job), you may end up being quite cost effective.
While we did have to spend some $$ to get things up to snuff (particularly so we could pass SOC 2), this pales in comparison to how much we would have had to spend to do devops and the usual server wrangling to get our use-case up and running in a typical elastic beanstalk sort of situation.
One area of difficulty was Oauth so if you ever need help implementing that in Jets feel free to reach out or read the public issue history of how we got it working.
In particular there's a theme of JS being totally optional: "Rails 7 takes advantage of all of these advances to deliver a no-Node default approach to the front end – without sacrificing neither access to npm packages nor modern JavaScript in the process." "The same approach is taken with CSS bundlers that rely on Node. [...] If you’re willing to accept the complexity of a Node dependency, you can pre-configure your new Rails app to use any of them"
That seems like a smart goal. They're not trying to go it alone, but they're clearly trying to draw some boundaries that keep the JS chaos/complexity at the edges.
If you want to learn it I think it's at a mature enough place.
Popular libraries like redux have been rebuilt to use hooks and simplify the integration.
I'd also check out Remix[0] if you wanted to get into a React framework. It's fairly new but extremely promising and easy to get up and running and even deployed anywhere (express server, cloud flare workers, deno, etc)
[0] remix.run
It was never clear to me why/when I would need React. I read and worked through some tutorials years ago, and while the reactive/one way flow pattern was nice, I never had a problem with Angular.
I recognize there have been many versions of Angular since then. And there are several web development frameworks, complex build tooling, etc. etc.
Meanwhile, I’m still writing services in Java that handle 20,000 requests per second for a service that brings in revenue in the billions of dollars a year. And I’m writing C++ (very straightforward, no templates, few uses of pointers, etc) for cross platform mobile code. I have some Spark pipelines all written in Scala.
Meanwhile the web stack continues to evolve… new technologies all just for rendering web pages. I don’t understand why. Admittedly there’s far more complexity in our use cases today than the HTML I was writing in 1999, but much of it is unnecessary bloat from bored developers.
But most of the times it's a pain, because of it not scaling well to larger projects. I've actually seen projects where controllers grow to the length of thousands of lines because the developers didn't feel comfortable with introducing new ones in the pre-existing codebase, due to how the scoping works, due to how they'd need to set up the data models and care about initialization of everything, as well as custom integrations with validation libraries and other JS cruft (due to it not quite being "battieries included", like the new Angular is).
Now personally, i really liked how they did error messages (which gave you URLs that you could navigate to, with a bit of context in them; though it would be better with a locally hosted docs server), but a lot of things were awkward, such as their binding syntax: https://blog.krawaller.se/posts/dissecting-bindings-in-angul...
Luckily, AngularJS seems to finally be dead, so we'll get to migrate to something else soon, hopefully. And the projects that won't will be red flags enough for the people who don't like such challenges to turn the other way - truly a litmus test of sorts.
Now if only the React ecosystem settled on standards too, that would be wonderful.
But alas. There is flux, redux, mobx, hooks, routes, sagas, thunk, observable, styled components, emotion, tailwind, react-antd, axios, fetch and so on and so forth. Edit: on top of, obviously, webpacker, grunt, npm, yarn etc.
Contrary to e.g. Rails, none of these come with React. You'll need to organize it all yourself (or go with something as react-boilerplate). You'll need at least some of these pieces to have something workable very early on. Things like redux or saga are not some "we've grown out of vanilla React and need additional tooling", they are essential to do things that practically every app needs: pages, communication with a backend, some styling, some consistency and deploying it to a public server.
When I had to learn a little ruby on rails I found the convention over configuration far harder to wrap my head around. It's quite nice to be able to see for yourself exactly how pieces are wired up and configured instead of having it magically done for you and dictated to you that it has to be done this way.
There are standards in some of what you mentioned. Mainly hooks, fetch, npm, and css.
Ruby doesn't "solve" css either, you're just using regular css files which you can do trivially in React as well (<Foo style={myStyles}/> and define myStyles as an plain old javascript object wherever you want - same file or not) or just include the stylesheet on the server response.
The rest of it, state management, webpack vs grunt, etc is pretty simple to select from and even in all that there are obvious choices - redux, webpack, npm that are certainly considered standard.
That was my entire point, yes.
There isn't much magic in rails, and just stepping through the methods in a debugger makes everything pretty clear if you do want to know exactly how everything is wired up.
The rest is nasty, nasty bloat. Saga in particular is one of the most pointless and libraries I've ever seen. Total solution looking for a problem.
There are some very clever things you can do with them, but this really need to know all the ins and outs of it first, and by the time you've learned them you implemented a giant nightmare.
Where sagas _do_ still make sense is highly complex async workflows, including responding to dispatched actions, "background thread"-type behavior, and lots of debouncing/throttling/etc.
But yes, I've heard of plenty of cases where sagas made a codebase unreadable, and it's a shame that they get so heavily pushed by some early Redux users.
FWIW, I've actually been working on designing a new "action listener middleware" that we'd like to ship in an upcoming version of Redux Toolkit. It started off as very simple callbacks, but by adding a few key primitive functions like `take`, `condition`, and `delay` I think we've been able to to come up with something that can handle maybe 75% of what sagas can do with a much smaller API surface and bundle size. I'd love to have you or anyone else using Redux take a look and give us some feedback on the current API design and let us know if there's other use cases it ought to cover:
My point, however, was that this is not obvious for anyone starting with React.
This is caused by the fact that React is "no batteries included", which means that you have to find the right batteries at a moment when you lack all knowledge about batteries in the first place. You search "how to send to backend" and saga's pop up, explaining why they are better than useEffect or redux or whatever (at a moment you may not even know useEffect or its downsides).
Compare that to Rails which has "all batteries included" (and which is a nightmare in itself, too, though), where all those choices are made for you. You can choose to ignore Rails' testing suite and instead erect an rspec setup next to it, but you'll do so consiously. Because that moment when you asked yourself "how do I test in rails" the One True Way was there, configured, ready for use and documented.
Both have tradeoffs and pros and cons. But the React community (with tutorials, this weeks best practices, breakspeed iterations of tooling) is not helping here. At all.
There are some default choices in Rails that I disagree with. E.g., I think it's too database-focused, and I build things that often aren't. But I still know I can get started with Rails and expect it all to just work. I know that people with Rails experience will be able to jump in without much pain. And then if I depart from the standard path, I have a good sense of where I might get into trouble.
Oh god, I'm so old.
in particular, someone said react is better for building complex systems. do you agree with this opinion?
if you want to try something different I'd go with svelte
which is better for building complex systems?
It's more important to pick one and just get started with it. You can do some reading about how they're different or their different philosophies but they all work.
It's more important to get started. If you want to build something to learn a skill to get a job, react is the most popular. If you want to build something to learn something new, any of them are a good choice. Just get started.
What's optional is whether you need to use node or npm itself as a developer-facing tool, and needing ESM support in the browser for the way they've done it means it's only relatively recently that that's been practical.
Sounds like bike-shedding to me. Eg. You start with solving trivial problems instead of the hard problems.
Usually the first thing that is decided is what framework to use, often by a non technical person that herd from a friend that is was good. Rather then having the engineers sit down and think about what are the biggest challenges, and what is the best framework suited to solve the hardest problems.
Could you let me know what your job title is - I am looking for something similar where I would like to work on some semi technical stuff and at the same time manage developers but not sure what title I am supposed to look for.
It’s good to start simple and only add complexity when it’s really needed. It’s unfortunate the current trend is to start with massive complexity.
He got fired.
- slow to compile and run
- easy target for spaghetti code
- test suites get sluggish
- hard to upgrade
- won't scale well
- with no static typing, large scale collaboration can easily break things
- metaprogramming hell
I knew a few people at university, who were pretty hyped about it. That was in 2008, I think. They used it at some companies where they jobbed and found it too limiting.
I was building customized stuff with bare PHP in those days and found it quite flexible. Later, the Rails hype came to PHP, but I already left for Node.js and never looked back.
Like anything else, Rails is good for some things & terrible at others. Rails tries to minimize developer time, at the cost of computing time (Ruby is not a fast language), and focuses on CRUD-type applications. Whether or not that's a good match depends on what you're trying to do.
I saw this as a sign that the time of these fully fledged frameworks was over and devs were craving modularity.
But, yes, I saw a bunch of recent projects done with Rails. Forem is built with it, for example.
P.S would have been happier if you had a better choice of words than "knocking myself out".
As the company scales they really need to break things into more services to distribute work and satiate work happening in other languages, but now that’s nearly impossible because of the mess they’ve created
Rails is great if your building a basic “dumb” web app, but rails folks seem to think it’s more than that and need to get their heads out of the clouds
Let me stop you right there. If you tell me Rails wasn't meeting your needs so you rewrote (X) in a different manner using Ruby + something else, I'd totally understand. Otherwise, all it tells me is that there was a tragic lack of deep Ruby knowledge, respect even, to begin with as the project unfolded. Often I muse on how in some ways it was unfortunate that Rails became such a darling in the startup community early on. It meant that a ton of people jumped into Rails web dev thinking they were writing "Rails". No, you're writing Ruby, and Rails just provides a nice set of base classes and some decent defaults and assumptions. If you end up with a giant wad of spaghetti mess, that's on you. It's totally feasible not to end up there, and plenty of projects end up in far better shape.
Really?
https://twitter.com/ShopifyEng/status/1465806691543531525
Github is in Rails. I mean, seems like it scales just fine.
It takes increasing the number of pods on your k8s which is how almost all teams deploy nowadays. Bigger amazon bills yes but the devops overhead isn't really larger in Rails,
I'm not even using node very much these days. Serverless is what I would reach for for most professional applications these days.
To cut a long story short, Active Record (especially at the time) wasn't super keen on generating super good SQL that would do as much as possible in database, and Ruby 1.9 arrived with stable ordered hashes. Then someone implemented basic ActiveRecord wrapper on top of key/value store (I think it started with Berkeley DB or similar), and from there NoSQL was off to the races as "new hip thing"[1]
[1] Meanwhile IBM IMS has been selling pretty well for last 40 years at the time ;)
Though I would also consider their exodus to be a good thing for Rails ;)
At some point, I gave up on even trying to use any Node ORM's because they were clunky and offered no value. It was easier to just drop straight to a knex session and write the queries natively.
[^] Mostly data engineering at work, and low level os/system dev in my spare time.
1. Elixir + Phoenix
2. TailwindCSS
Elixir because you can build a monolith with it and everything is naturally separated by design. The runtime makes it impossible to hurt yourself. It addresses virtually every web use case in an ideal fashion that balances development speed with long term maintenance and scalability because of the language design trade offs.
TailwindCSS because it removed the decision about which of the million frontend stacks in should be using. It makes it so easy to do anything I can dream up without feeling like I need to hire somebody to help with a pet project.
And honestly, even though I like DevOps and database work just using Heroku/Fly/Gigalixir so I don’t have to worry about it makes my life easier.
I tip my hat though to people diving into Elixir --- it is definitely a cool direction and one I would follow if I weren't already so sold on Rust/Crystal/etc.
personally, I still enjoy the extreme dynamism of lisp and lisp-like langs (julia), but we may never see a resurgence of them in popularity
I can’t think of another language, even Rust, where you could run a full database inside your codebase without negatively impacting everything else.
That BEAM runtime just makes things possible that aren’t in other languages.
But I feel no typesystem would bite me in bigger project.
def foo(mymap):
blah
Has no real information about what my map is. In contrast, a staticly typed language like Java would have public static HashMap<String,Integer> foo(HashMap<String,Integer> mymap){
return mymap
}
which encourages you to have a lot of classes defining different types of things, which is rigid, but at least makes it clear what exactly the function is expecting. Elixir is somewhere in between, where you'd write def foo(%{"username" => username, "password" => password}) do
{username,password}
end
which makes it abundantly clear what the function expects ( a map, with keys "username" and "password"), and handily unpacks those values for you, making it feel more immediately useful than "In the future it'll be nice to have more clear code", which helps with adoption. def foo(login_data):
match login_data:
case {"username": "foo", "password": "blah"}:
return True
case _:
return False
In addition you can use type hinting: def foo(login_data: dict[str, str]) -> bool:
match login_data:
case {"username": "foo", "password": "blah"}:
return True
case _:
return False
Unfortunately I don't think you can yet do the neat argument unpacking as per your Elixir example, but it's some of the way there.IMO it's a disservice to compare Elixir's typing to languages like Python, and we need a new category to distinguish the two.
This is exactly why, in 2004, I moved from Java (Struts/Spring/Websphere/XML/...) to Rails. History repeats but we never learn. Kudos to Rails for remaining relevant.
Rails is nice in terms of getting the project set up, not bikeshedding about the tooling, and working with the db. But the actual coding has been painful for me. I really dislike working with a non typed language. I dislike optional parans in function calls and optional braces for hashes. I dislike all the magic of rails. I never know what is going on because there is some functionality that inherits from a rails class or some other part of the code base. I would rather write a bit more code for a bit more clarity. Maybe if python were typed I would like Django? But python has all of that nonsense around virtualenv.
Spring has been ok, but not great. Too much bloated abstract factory creator nonsense. Dependency injection never really clicked for me. All of these annotations. I quite liked plain Java but Spring just felt like this monster.
All in all node(express) has been the nicest for me.
In express there are packages for those things, ie https://www.npmjs.com/package/express-session. Agree it would have been nice as part of the express library.
That is a great question. Is it the job of the tooling to prevent a novice developer from shooting themselves in their foot? Do we need higher-level abstractions in our frameworks that are analogous to memory safety in programming languages? Perhaps.
Alternatively, I don't think that security practices are particularly hidden. Anyone who's used the web knows has used a login form. I would give most novice developers the benefit of the doubt that they're going to be curious and look into that.
I would argue that it is, in part, their responsibility to learn these things. It's our responsibility perhaps as stewards of the secure web to teach and enforce best practices. I don't think baking in these best practices into frameworks does these developers any favors, except that it allows them to focus on something else.
TypeScript to me is the compromise I'm willing to settle on. It is also lackluster from many aspects but day by day it gets a bit easier.
Types can be checked with mypy: http://www.mypy-lang.org/
For Django, there are these two typing packages:
- https://pypi.org/project/django-stubs
- https://pypi.org/project/django-types
I can't vouch for them, but it looks like they're being actively developed.
I like the idea of full-stack JavaScript (or TypeScript), but last time I tried to use Node for a back end, I couldn't find anything that compared to libraries/frameworks like Django, Rails, SQLAlchemy, etc.
The lack of good documentation is painful and often treats me like I don't already know the concepts involve.
Sequelize isn't as intuitive as Django's ORM either imo.
Turned out to be painfully slow to iterate. The ORM needs constant attention to join or prefetch queries.
Switched to Prisma and it's an utter joy. If the typescript has no errors then there won't be runtime errors.
Sequelize is a multi generational mess. It's a huge time waster.
Could you elaborate on that ?
I personally like the functional aspect of sequelize.
Working with Prisma: if it compiles (and you don't have a business logic error), then you usually won't get any runtime sql errors.
You don't have type safety with sequelize.
I had to write my own types around the existing ones to get getters and setters to work.
I haven’t checked out Prisma. Thanks for the tip.
Prisma has a great API for this, and it's easy to tune. By default is prefetches and selects related even several levels of joins deep.
However the reason I don't use Rails as much is that I'm not writing a lot of "full-stack" apps. A lot of the work these days is gluing together various SaaS services. Okta/Firebase for Auth, Contentful for CMS, Stripe + Webhooks for Commerce etc. I just don't do anywhere near as much "CRUD" style programming as I used to do earlier in my career, which is both a comment on my career and the state of programming today.
I'd love to see a project that wraps up a bunch of best-of-breed technologies and creates a full framework and doesn't try to be all things to all people. ie React for Front-End, Bookshelf ORM, Express Server etc (pick your favorites, but have an opinion that evolves but only in one direction.
This is also my only complaint with Rails.
I'm a programmer, not a wizard, and I'm not good at magic.
We are surrounded by magic (which only means things we can not realistically be bothered to take the time to really understand, in contrast to things which are incomprehensible). I have no real clue why the terminal works. I have no real clue why my OS works. I have no real idea how TCP/IP does its thing. Sure, I can use them – but I couldn't really explain and much less recreate them.
What I need in all the above is replicability. I do x, and I know y is going to happen. Get x, do y. This is true in Rails.
If I really wanna know more Rails is open and easily explorable. No one is preventing me from finding out how any piece of the "magic" works.
"Magic" class inheritance is a thing in JS as much as it is in Rails.
What is so special about Rails and "magic"?
In Typescript, entities have types and when you misuse something the typescript checker tells you while you're coding why, that's not what you're supposed to do. You can super easily track down the type and navigate the code base to the source and adapt either your code or edit the source. Easily. With rails, you're often required to do mental gymnastics to debug simple things, after the fact
I 110% agree with you.
This is Rails striking again!
"Don't look at the magic, just memorize it." might as well be Rails' slogan.
Convention over configuration really just means "Memorize all my conventions, and don't ask why I picked them".
Great for the case where your use-case is in line with the chosen conventions and you don't want to think all that hard (or you just need to pump out content - like a contract agency). Pretty terrible for just about everything else.
0. https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/async...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Even...
You can go from nothing to mostly full-fledged promises in about 200 lines of code: ex - https://www.promisejs.org/implementing/
async/await is pure sugar on top of promises (it's literally just wrapping the rest of the function in a .then() for you, and coercing the return value of your function to always be a promise)
Not to mention that part of the issue with Promises is the various polyfills invented before broad acceptance, which is a separate can of worms, and a different type of complexity than the (relatively) heavy use of metaprogramming in Ruby (relative to JS).
It really isn't that common just like it isn't that common to do it in JS or in Python. Some people used to do that shit a decade ago, it became frowned upon and I don't really see it anymore.
class Foo; puts "foo.rb was parsed"; end
is a simple example of nothing is really special.
I'll state my case as clearly as possible: The magic in Rails REQUIRES memorization... freaking everywhere. And it provides virtually no hints to jog your memory.
There's just too much tooling, hidden away out of sight, and applied through shenanigans with Ruby that other languages/frameworks make MUCH more obvious.
Simple trivial example? Rails fucks with imports left and right. Rails allows you to not even write a require statement half the time - it's just going to load things from places. Hope you have that list memorized.
Does it save you some time? Yes.
Does it make the code look "Cleaner"? Sure.
Does it make my life a fucking chore every time I have to run a damn console to find the source location of an object at runtime because it's entirely unintuitive about where it freaking came from? Damn right it does.
---
If you started early in your career with Rails - you probably don't notice this. But if you have experience with a solid selection of languages (ex professionally I've used: GoLang, C, C++, JS/Typescript, C#, Java, Netlogo, Rust & Ruby) I find the discoverability in Ruby/Rails about the lowest on the list.
Very fast to work with if you happen to have it all memorized. But that's about the only compliment I can give it.
In my book it's a write-only coding environment like everyone used to complain about with Perl and PHP. People crank that stuff out really fast and move on and leave future generations to suffer. But they love it, of course.
Because to me - RoR is in the death spiral period that the original ASP.Net was in before Microsoft threw the whole thing out and started over with the Core version.
Namely: Rails trys to give you opinionated best defaults, but the "best defaults" have changed dramatically since the framework came into existence. So you end up with 6 very different set of opinions as the framework has evolved, and the documentation is poor (honestly, at least ASP.net had okish docs - I find Rails docs pretty damn bad) and you get a complete wash on 3rd party sites trying to find relevant info for the version you happen to be using.
Also - Unlike MS and ASP, Rails doesn't even fucking try to keep naming consistent. They seem to favor making the syntax as close to natural language as possible, often deprecating the old syntax in favor of new method names solely "because it reads better". Which drives me freaking nuts.
Inertia will keep it running for a long time, but it's not the thing I would pick for greenfield projects anymore.
1.
These are fair criticisms. These kinds of problems can also be difficult to demonstrate to others who may help.
For example "some function `f(x)` gives 5 when it should give 7" will get an answer in 5 minutes on stack overflow, whereas "my thing's not working and I don't know why" will receive 4 downvotes and no answer in the same time.
2.
I tend to be the kind of learner who doesn't sit down for 30 days and read the docs cover to cover, but rather I start using the new tool on day 1 and figure out what I need to know as a I go. But rails rewards the former approach (i.e. reading through the rails guides - or even just skimming them). This may take a few weeks, but it gives the ability to at least know where to start to look if something has gone wrong.
3.
> And it provides virtually no hints to jog your memory.
I kinda agree. I feel like this should be easily addressed (although I'm not totally sure how).
What's interesting to me about this comment is that among the languages I'm familiar with that you list, the difference between the best discoverability and the worst feels way larger than the difference between the worst one and Ruby. To me, C is barely any better than Ruby; sure, Ruby lets you define methods/types at runtime, but C doesn't even _have_ methods, making finding all the things you can do with a given type way worse in my opinion. Plus, you can still have some wonky generated stuff with macros, although I'll concede that's usually less common than Ruby metaprogramming. Java, C++, and Go are a bit better, since you get a namespace instead of just a random identifier without context, but these namespaces are generally split across multiple files, so in practice I would need to rely on tooling to do this for me, and at least with RubyMine this wasn't in practice _that_ much worse.
Ex: C doesn't have methods, but if you store most of your data in structs then you can easily do two things:
1) find all the places where the header defining that struct is included
2) Do a global search for the struct name
Both will present you with a nice list of places that data is used, and show the functions that accept it as an argument.
Where as with Ruby - I basically have to use RubyMine to get anything even sort of working, and even then it chugs along very slowly trying to do it. Solargraph in VSCode doesn't really work at all (at least 50% of the time it finds no definition for me) and just using a basic editor is a nightmare. Sometimes you can do a global find for "def [classname]" but that only gives you the definition, not any of the places that use/modify it.
Basically - Ruby is one of the few languages where I feel like global search just doesn't work well, and it also eschews import/require/include statements when used in Rails. It's just a tangled mess, and there's NO way to unwind it without tooling, and even the tooling struggles (RubyMine is a guaranteed way to get my fans running at full speed for large projects, and it's the best I've used).
You just see these functions and there is no require in the file to tell you where they come from. Rails just loads that shit from somewhere. It could be from a mixin, it could be from one of the 50 classes in your hierarchy, who the hell knows. You press jump to definition and rubymine just fucking chokes and gives you like 30 different method definitions with the same name in different places.
I don't know how much blame to put on Rails, Ruby, or the teams I worked on, but in the end it was very frustrating.
Aside from that I like Ruby a lot, and Rails only a bit less. But it's a big aside :)
After using Rails every day for 12 years I know pretty much all the ins and outs, and what is "magic" to others is just the robust tooling I love. Just like any tools, they are overwhelming and daunting when you don't know how to use them, but once you become proficient with them, they make your life so much easier. While it might be difficult when the "magic" doesn't do exactly what you want for your edge case, when you have a sufficient level of mastery, it's easy to find a way to adapt/modify/override the tooling and make it do what you want. Further, many times the tooling is there to keep you from doing things you probably should not be doing, and this kind of strict, opinionated, best practice enforcing philosophy has gotten me out of trouble at times, and I think it makes it much easier for engineers to move between Rails codebases and start being productive even faster.
I've done plenty of Node/JS/React and I honestly do not understand how people can prefer to use these stacks over Rails. For full stack web dev, Rails is such a pleasant place to work every day.
Rails is 17 years old.
Im a noob starting a project in Spring and I get lost in the jargon. I find that all the Spring knowledge I’ve gathered is to know what is NOT written in the code that Spring is doing for me.
In other words, feels like knowing Spring is being able to read between the lines and placing annotations more than building with it. Which is fine, but it’s easy to get lost when starting out.
It’s also for me to find help since the community seems much smaller and none of my friends are interested in helping out because they don’t want to learn Spring.
I've found the official documentation to be very detailed, so it's helpful if you really need in-depth knowledge, but if you don't it's a bit hard to parse out the relevant bits. Copying something from the official guides seems often the easiest way...
In regards to the community, I didn't find it to be much smaller? The stack overflow tag is very active. I have the same experience that nobody I know wants to learn Spring out of their own volition though.
This is my #2 problem with Ruby, and it's also the reason why a lot of folk love it. I think of macros in the same way I think of RegEx, if you're writing one you better hope it works perfectly because chances are that you'll be the only one to maintain it.
Other Ruby "features" that I dislike:
1. Blocks + Procs + Lambdas are all function-adjacent. Can't we just call them functions?
3. Out of bounds indexes on Arrays/Maps return nil.
4. method_missing() is super cool and super abusive. Again it feels like magic when functions come from nothing.
Well, Ruby has functions, they're just called Procs. Lambdas are a special, more strict breed of Procs, and blocks are just (pretty complex) syntax sugar for passing a Proc to a method. The main function-like concept is always a Proc.
> Out of bounds indexes on Arrays/Maps return nil.
Calling the #[] or #slice method on an Array with an out-of bound index returns nil, calling the #fetch method raises an IndexError or returns an arbitrary default value. You can use whichever suits the situation.
Let me assure you, there is 0 magic in Rails. Just because something is available to you via a convention doesn't mean there's magic, it means you haven't read the docs and don't understand the convention.
There is a ton of magic in Rails. It consists primarily of magic. I've been doing Rails since <1yr of introduction (Ruby for longer than that, and Lisp for longer than either). I'm very familiar with metaprogramming. Metaprogramming fits the canonical definition of magic in this context.
Ruby, and Rails, also makes it very easy, and seductive, to add more magic. This is powerful, but dangerous. Like Lisp macros. Understanding the magic is not just a matter of "understanding the conventions" and reading the docs.
People are realizing that you can accomplish quite a bit more with hypermedia than you could in the past, and that the complexity of javascript stacks isn't worth it in many cases.
Older, mature hypermedia-based technologies like rails, django, and even PHP, will experience a resurgence and a lot of older lessons and techniques in web development (caching, SQL tuning, etc.) will be rediscovered.
I have a dog in this fight, w/ htmx, but I think we are increasingly seeing evidence for this move.
The biggest CMS of one of the biggest languages is moving away from the approach you call hypermedia by implementing a JS-based editor and REST apis. Effectively they are building a headless version on top of their legacy platform, which can be used like a JavaScript stack.
This can be used as an argument for the hypermedia approach: "Let's just use this thing for now, we can always implement our SPA inside it later, if we need to."
Which CMS is this?
Not sure what you refer to as hypermedia.
In the first part of your comment I assumed something like a new version of Flash. Here you seem to simply imply http/hypertext.
But then again, those technologies where never lost (to need to be rediscovered). They're as popular as ever, people just add more stuff on top, at the client JS layer.
i think it will rather be in non-javascript technologies with strong existing hypermedia infrastructure again, like rails, django, etc
the front-end component model is anti-RESTful and is really a mechanism for handling the complexity of the current client-server approach, it becomes significantly less important as hypermedia is re-embraced
Hypermedia also doesn't play well with offline-capable applications, which limits its use cases.
we just disagree, the future will tell us who's right
don't worry! If you need to kick out to some front end scripting we have a solution for that as well:
So no ugly javascript! ;)
At some point, stuff needs to be maintained. You can still start and drive that 1967 car, after all.
I just started with HTMX and so far I think it's really promising. Similar things happening with Rails and Hotwire.
It took a while for these frameworks to accept that JS and the frontend are also important aspects of the stacks, and hard to avoid if you want to build modern applications. But now that they're picking up, heavy JS frameworks start making less sense.
Rails is opiniated, and I love that: https://rubyonrails.org/doctrine/
Edit: Oops, looks like the new website they release somehow fudged the doctrine page. Here's the Wayback Machine link: https://web.archive.org/web/20211126010919/https://rubyonrai...
Update: Oh, they changed the link, here you go: https://rubyonrails.org/doctrine/en
And I see very little reason to pick Rails over PHP over Django over Node!
Whatever works for your team is what matters. I bet you could find a Fortune 500 company that uses any one (or all) of those.
Node's easy, as it's technology, not a framework, so you'd pick Rails over it if you wanted a lot out of the box. JS also "thinks" differently than Ruby (callbacks, and now async, pretty much everywhere). PS - If you haven't played with lots of curried functions in JS, it's fantastic (IMHO).
If I wanted a more same-same comparison, the choice is between Sinatra and Node, and IMHO that's a lot more even (and for me, broken by one of them being in Ruby ;) )
Django's more subjective, but my experience with it was very not-great. There's a lot of decisions in Django that look good on the surface (apps, for example) that then don't pan out (apps all end up blurred together, for example). Particularly compared to Rails, I found Django waaay more boiler-plate and frictiony (particularly the migrations), but that's fitting for a language (Python) that's actually more lower-level than expected. Python (and Django) are opinionated where Ruby (and Rails) are welcoming, IMHO.
I was really happy when I was able to stop using Bluebird and switch to JS promises, and formal async/await in JS was a game changer: it cleans up code significantly. It is hard to use languages that don't have async/await now that my brain has become so habitualized.
However, I'm a little bummed currying was effectively nixed (or just ugly) with JS module imports; require() had an edge there.
But the reality is that this comparisoin is what you end up with in real life decisions. Even if you pick a Node framework like Express, it will only give you a handful of tools, not really a batteries-included framework like Rails.
I haven't come across a Rails-like framework for Node. I wonder why? Didn't people try to make it? Is it because of the language specific features and Node ecosystem that it's hard to come up with a coherent, opinionated, all-inclusive framework?
I hear over and over that rails doesn’t “scale”.
Performance wise, we have never had a problem scaling rails itself. The issues were always at the database level. Most slow endpoints (1.5s+) are 10% Ruby, 90% Postgres.
Even if Ruby was magically infinitely fast, these endpoints would go from 1.5s -> 1.35s.
Optimizing data infrastructure gets 10x returns compared to the application code.
Maintenance wise, it’s a bit harder, Rails loves to put everything in the global namespace. This comes down to your team being conscious of properly namespacing different logical parts of your app.
Asking for.... a friend.
I do it by having a new folder "components" on the Rails root and adding `gem 'name_of_component', path: 'components/name_of_component'` which looks like a vendored gem.
Rails engines has the ability to "isolate_namespace" which is I think the default for a new engine. This is where you can avoid global name spacing issues where each component can be thought of separately. Effectively, you have something _kinda_ like a microservice but it runs as a monolith. And if you need you can have each component depend on others so long as you don't wind up in a loop.
Note: I have a component "common_models" which is just for commonly used items across various components. The main app should have nothing in it's Rails.root/app since you instead have components.
I'm not related to this but here's a basic idea: https://cbra.info . (Pretty sure the author of this page made the Railsconf talk that inspired me to move to this years ago.)
I’ve primarily worked as a Java dev for the past 20 years, but I’ve got significant time doing python and one non-trivial Rails app.
The funny thing is I’m most comfortable and I believe most productive in the Java ecosystem, but only because of the time spent working in other languages. Coming back to Java after python, one gets a better feel for what’s essential and what’s cruft. Similarly, when Rails first came out, it can’t be understated how revolutionary it was with respect to web development. Coming from the J2EE universe it was like the true essence of web development had been hidden from us with servlets, JSPs, wars and ears.
That being said - I’m happy being a Java - well JVM at least - developer. The ecosystem is alway changing and often improving, but I assure you it wouldn’t if not for the evolutionary pressures of things like JS & Node, Ruby & Rails and Python & Django.
I love kotlin as a language and enjoy working with spring boot but the hype in the JVM community around JSON API + React SPA does make me wonder whether I'm moving away from it philosophically.
I'm particularly excited by Spring Native right now. Having a Spring Boot app startup quickly and use less memory will fit heroku-like PaaS environments perfectly.
"JRuby is known to consume more memory than MRI. You may want to run standard-2x dynos for optimal performance."
I'm glad I ventured out of my Java only mindset however. Lots of interesting things going on but decision paralysis sucks.
20 years ago, Java development wasn't that complicated. Big consultancy came in and complexified the ecoystem just for the sake making the entry level way too high. A Rails developer only needs to know Rails and Active record and maybe Capistrano and some server.
A Java developer has to know Servlets, Glassfish, Tomcat and other containers, JSP,JNDI,EL, JSTL, JSF, JDBC, JPA, CDI, EJB, Hibernate, Spring, Maven, Gradle and God knows what to find a job.
For a beginner, the documentation is also all over the place. Java the language is improving sure, but some people are still stuck with maintaining struts applications to this day, with tons of XML files...
Just reading these make me depressed. I'm taking over a JSF project that uses gradle these months which puts even the complicated old spaghetti gulp build files to shame in terms of complexity.
Even more confusing is that there are some people who love that complexity. They are actually proud of it! Why would you have a globel gradle file in your $HOME that has project specific configuration? Why does your stupid project only run with some specific Eclipse plugins? Why does it take 2 days of depressing configuration work to have a running instance? I used to love Java! What happened when I wasn't looking!? They tell me "but you do it once!!", I digress.
In other languages there might be multiple frameworks and multiple libs all of which might do none of just part of what you need and if you find a lib you might not find an integration into your framework and need to build that yourself.
Rails was so big and the community was/is cooperative enough that you usually get fewer libs that are more complete and more likely to fit you needs and come with rails integration.
No need to test 10 or more libs to find out all of them sort of suck and then do it yourself or chose the least sucky one and integrate it yourself. THAT is what maid Rails productive and at times frustrating (you often only deep dive the components once something goes wrong).
Long term it will be interesting to see how many companies run with setups that are Node.js heavy in comparison to not just Rails but also Python, PHP and even Java, .NET and Perl (yes old but not dead).
Perl was one of the early languages and I don’t think there will be as many projects in it as there are in PHP. Python has a good amount of stuff and they didn’t really have a time of heavy hype (like PHP, Ruby on Rails or Node.js enjoyed) and Java and .NET are going to be more heavily traditional corporate than the rest.
Would be nice if somebody knows a link or two to explore this a little bit better.
When I think of all the half backed JS projects I’ve looked at when searching for a solution and compare that with Ruby, there is a difference.
Things have been moving so quickly in the JS space and because the JS community is so prominent on Twitter. It's ended up with a lot of JS 'influencers' who feel they have to come up with a new hot-take on code smells or the latest cool new thing every week in order to stay relevant. They tend to default to exclusionary behaviours whereas Rails is a lot more friendly.
As you mentioned, the Node.js ecosystem is full of specialised libraries to achieve typical use cases such as authentication/authorisation, ORM/persistence, etc. The Nest.js documentation is a great reference as they include a list of recipes for all those common scenarios and how to implement them in a Nest.js backend.
I had a decent experience with TypeORM after I spent time understanding how it works under the hood to optimise the queries (notably by defining the relationships better).
I agree that for side projects, underfunded startups and especially for product/business-focused founders, using the quickest magical prototyping framework is definitely the best idea so I agree with the overall sentiment of the post, just not the specific conclusion that Rails is the best way to go in 2021. I still believe strongly that having the same language on the front end and backend is paramount to developer productivity.
No authentication built in, no ORM, no ActiveStorage, ActionMailer, no nothing really there.
https://laravel.com/docs/8.x/validation#rule-unique
How to do a unique validation in nestjs (didn't find it in the docs, so had to Google it):
https://gist.github.com/zarv1k/3ce359af1a3b2a7f1d99b4f66a17f...
No thanks.
This is still apples vs molecules to mount your own apples.
What part of that comment says anything about layers or maturity?
By that rule I could compare rails to express and say they are about the same.
A much better comparison would be either Blitzjs, Nestjs, redwoodjs, featherjs, or several other full stack js / ts frameworks. I'm pretty sure these frameworks were inspired and influenced by Rails
React is way better on the view side than ERb/HAML/whatever.
I miss ActiveRecord. Prisma is relatively clunky. I like having fat models integrated with the DB.
It also feels like I'm fighting with the type system because every variation of a row with different joins becomes a different type. I'd rather be lazy about joins.
I'm the developing a rails backend with a Vue front-end, and the more I work with js, the more I'm happy that I don't have it everywhere.
(Yeah I know this post isn't terribly informative, but neither is the article, so I'm expecting some light-hearted posts)
Well, one of them was done in ten days by a guy who liked Java and the other one was done in a few years by a guy who liked Smalltalk, so...
And that's part of the problem: if what we'd started with was Java--, we might not have quite such a mess today.
I open a file and I feel completely lost.
Anyone starting out with backend webdev should learn Python Flask. There is no gentler and more thorough way of learning web fundamentals, whilst still being productive from day 1.
Yes, almost every other language is still more productive, but all that tooling gives you less and less each year.
My team uses a Rails backend and React apps on top. For us, React apps compared to Rails views just about cut our feature delivery time in half.
Of course, it depends on what domain you are working in. Dynamic frontends on Rails are a pain compared to React and probably some other front-end JS.
That said, on the backend Rails is a very mature framework that is hard to beat on most things.
From my experience with Flask (albeit, this was years ago), it was a bit more complex and ending up with circular dependencies was common.
This is also pretty much obvious from the get-go. When handling a HTTP request, the morally correct function is something like a function which takes a request as a parameter and returns a response.
In flask, for no good reason, a lot of things that are only accessible inside a request get put into global objects, and if you try writing code that accesses them outside of the right context, it will simply crash. You might accidentally refactor such code to the wrong place and you will have no idea until it crashes. This kind of design on top of a dynamically typed language is kind of like drinking poison and then shooting yourself.
Flask is full of insane things like this and it boggles the mind that it ever got as popular as it has. I suppose there weren't many alternatives.
Everyone talks about the complexity of the tooling and I have no clue what they’re talking about. This is from a backend perspective. If you jump on the TypeScript bandwagon, which makes everything infinitely harder, then maybe, sure, I’d agree with you. But JavaScript is dead simple to use.
Even now in frontend land there’s still innovation. Vite has been an absolute pleasure to use and spinning up a React app takes minutes. The irrational hate for JavaScript is really weird.
I resurrected a Python project of mine after 7 years. Upgraded the dependency management to Poetry, upgraded the major version of Flask. Boom. Back in business. Try that with a modern Node project after 7 months.
I'm sure there are modern projects that can make this painful, but if you're judicious about dependency management and staying on the LTS version of node, its rare you see any major headaches in our stack.
Even for super old / legacy services (ones without automated dependency mgmt through CI), it takes maybe 15-30m to get everything up to date.
I took a project with ~20 top level dependencies and around 5k lines of Python / Flask (plus a lot of tests). I YOLO'd upgrading everything to their latest versions in 1 shot including Python 2.7 to Python 3.7, Stripe API versions and everything.
I did that around 2.5 years ago and it took around 45 minutes. The app was using SQLAlchemy, Celery and had a bunch of things you'd expect to see in a SAAS app (users, custom admin, payments, custom CLI commands, migrations, etc.).
Like, yes of course an actual RAD framework has more things built into it than a server runtime. That's kind of why they exist.
Your programming environment should more or less reflect your requirements, strengths, and priorities, and starting with plain Node makes sense for a development style that OP just doesn't seem to want to follow, so he's spending a ton of time building 'boilerplate' to try and shim his process into his tools when the tools should be the ones doing the work for him.
Like, all that stuff about CRUD and auth. Just use Prisma and Passport?. No need to twist yourself into a knot building the same abstractions over and over by hand, the things exist and are there.
I am documenting my process of building my first web app here: http://tbonesteaks.gitlab.io/blog/. Just started it today, so it’s rusty.
They made vague statements that to me seemed laughable without examples.
2 weeks in expressJs? doing what?
2 days in ruby? again....what?
is the author bad at bootstrapping perhaps? do they overcomplicate it.? I need examples to appreciate their insights. otherwise I cannot fathom Hello world taking two hours in modern node.
A few years ago, in a previous role, I was forced to use Java to start a new web app. I spent a couple months reading up on things, and trying to find a comprehensive example of a CRUD app in Java/Spring/React. I finally admitted defeat, and corresponded directly with the author of JHipster, and he pointed me to an example he had on GitHub, which had never come up in searches, but, unfortunately, was so out of it date, the code wouldn't work in modern versions of the stack. However, I finally cobbled together a working "show" page with nested objects, as ANY real-world web app will need to do. At this point, I again got stuck at trying to figure out how to update nested objects in a form.
As a mental exercise, I rewrote everything I had done in 6 months in Java/JS in Rails in 2 days. These 2 lines of Rails...
class BankAccount < ApplicationRecord
self.table_name = 'offer'
belongs_to :owner
end
... represented over 250 lines of Java/Spring/JS. A lot of people around here hate that Rails is "doing so much for you," but do I really care to write every line of code required to define the relationship between BankAccount and Owner to the compiler, when it's a simple many-to-many connection implied by a foreign key?I found another job.
P.S. There's a lot of talk on this forum about Typescript and how great it is, but very often in my months of trying to write this application, I couldn't get the types to line up through the stack, and just had to use generics.
When you say "use generics" do you mean typing things as `any` ?
imo the one I like best in nodejs is Blitzjs https://blitzjs.com/
FoalTS https://foalts.org/ is nice too and there are several other full stack frameworks like Nestjs, FeatherJs, and redwoodjs
For instance, you can bootstrap a powerful Admin panel for your Rails project in no time with https://github.com/motor-admin/motor-admin-rails gem.
Clearly it is not going to be as mature as RoR for a long time, but as someone who knows enough JS to be dangerous it looks like an appealing option, especially when faced with having to learn an entirely new language.
The really amazing part of JS cruft is how constructs that should have been dead for 20 years just keep coming back. E.g., the keyword "with" is a footgun for hiding object scopes that mostly disappeared before I learned JS, but then it showed up in Vue of all places!
Variables are scoped either to blocks or their enclosing functions, depending on how they're declared. Functions either create a context for the keyword "this" or not, depending on how they're declared. Both of these traits are maddening for learner.
JS uses a prototype chain and prototypical inheritance, but now also has a classical-looking class-based syntax as well. There are half a dozen ways to create an object and it's a much bigger hurdle for people to learn than Ruby's more or less mainstream choices.
Building larger apps in JS on the back-end also means spending a lot more time thinking in callbacks, promises or async than working with Rails would, too. Sometimes it's inevitable but it's a hurdle for learners.
As to the low level nature of Node/Express vs something like Rails or Django, I've tried SailsJS and Loopback, which are probably the closest comparisons in Node, and ending up regretting it. Every time I chose a high level API framework / ORM, I felt like I was fighting it or trying to find a workaround for the simplest things.
I now choose Express or Koa for most projects.
Well there's your problem. If you were to `npx create-next-app` you'd have most of what you want already done for you.
Someone throws you an apple - what is this food that you can eat without peeling? Think of all the time you can save not peeling fruit! Surely you must tell all your orange-peeling friends the good news?
I would love to hear more about what you are doing, and perhaps more importantly, how you are doing it if everything is so incredibly difficult for you.
Ruby only has one thing going for it, and it's not a very unique thing and you can get the same thing in a lot of other places: it has batteries included(and then some). This can make you very productive from the start, yes, but it can also constrain you to work in exactly the way the authors intended and otherwise make your life difficult if you have needs that just fall slightly outside of the garden path.
With node, you have nearly an infinite number of choices. But if you pick a stack, and you set it up properly, there is nothing preventing you from moving at speeds similar or surpassing RoR, and usually without any of the same limitations.
I am currently building a full-stack application in TypeScript using React and GraphQL on top of Next.js. It is easily the most productive stack I have ever tried, even though it took some work to get there. I can change a database model and the change will propagate through my entire stack all the way to the frontend, giving me type errors in every place I need to change anything, and things like that. There are great "plugins" for nextjs like next-auth which make auth laughably simple, and then you can pick between whatever ORM you want(We are using Prisma, which has been great).
With that said, if RoR fits your use case and meets your performance demands and it makes you more productive.. well, that's great news. Seems like a no-brainer to go with it then.
I've worked many years with Django (doing old style MVC), then moved to do all the SPA stuff (worked with React mostly and some Vue). Now I'm back to MVC using Laravel and Livewire and it is simply awesome. If the decision is on me, I'm not going back. Laravel is awesome, and current day PHP is not 10 years ago's PHP the same current day JavaScript is not 10 years ago's JavaScript
I've also grown like sqlx (both the Rust and Go versions, despite them not being related as far as I know). The methods for mapping directly to structs work really well and captures one of the biggest issues I've had (literally the object-relational mismatch).
I feel like I'm in a state of decision fatigue with web frameworks. I've used many shallowly, but I just never know if I'm making the right decision. It's probably safe to assume the best bet is the one I choose and stick to though...
Also if you'd like to manage the tables with SQL there's an easy way to generate the models from the database schema (https://docs.djangoproject.com/en/3.2/howto/legacy-databases...). I've used it before at a startup to migrate from hand coded schemas and migrations in SQL that only one person was brave enough to touch (they had no way to run things locally) to a full consistent REST API for like 20 tables ready in 2 days.
I'm also managing an SQLite db on a mobile app that uses hand written SQL (with 20ish tables and a few 100 queries) and any changes to the database end up being a nightmare of manually editing raw strings.
But, the whole point of using a framework like Rails is to let the framework make certain decisions for you, so you can develop quickly according to convention, and not think of lower-level technical decisions. Bypassing the ORM certainly works against that.
However, most of the other features of these frameworks are just bloat, added complexity that doesn't really make things easier than writing vanilla $lang with rock-solid libraries.
For example, in Go: URL routing, request handling (middleware), html templating, websocket communication are all trivial to implement with standard or well-known libraries. But it's the DB interaction where things get tricky and very code-heavy.
I'm trying out an approach, leveraging pgx and the new Go generics, where I define a simple generic Wrapper struct with some low-hanging fruit methods: CRUD, filtered+pagified lists, unique constraints, etc.
How? `encoding/json` and Postgres JSONB columns. The generic Wrapper is hardcoded with a simple and flexible table schema: an id column and a JSONB column (I also added some timestamp metadata columns as an experiment).
The end result is that I implemented a dumb "ORM" with around 200 lines of idiomatic Go, and can do the following:
wrapper := Wrapper[MyStruct]{pgx.Conn, "mytable"}
record := wrapper.Insert(MyStruct{some,real,data}) // returns a generic Record object which includes the DB id and pointer to the (actual, not interface{}!) struct, as well as other metadata perhaps
record.Data.myField = time.Now()
wrapper.Update(record)
for i, record := range wrapper.List(Params{}) { \\ do stuff with all the MyStructs }
...and so on and so forth. The goal here is not to implement a perfect ORM (e.g. pointer/FK spaghetti) but to secure that initial productivity boost of easily ACIDifying my data. As my data model gets more mature, I can individually migrate these "weak" JSONB schemas to proper, (de)normalized, relational Postgres schemas and define their data access appropriately.
I'm constantly monitoring the logs during development to make sure it's doing exactly what I want. And the odd time when it's not the answer is usually within ORM api itself and doesn't require me to shift to raw sql.
This is why I never understood the argument that ORMs are for people that don't know SQL (not to suggest you were making such an argument). If anything being proficient at SQL makes you that much better at handling the abstraction that the ORM provides and that much better at examining the resulting queries.
My read on this is that many of these apps were begun as PoCs/MVPs and as the original engineers have tried to scale, they've lost interest. So we have a large amount of 5-10 year old code bases that are looking for maintainers. One friend in particular contacted me and asked if I knew anyone who'd be willing to contract with his firm to upgrade a Rails 5.x app. This tells me, they had no one on staff that could do so.
So yes, the need for Rails devs is large. The popularity of it? At least in my area... not so much.
I thought I had moved away from Rails into Go (I find the two very complementary), but I got pulled back into some solid, meaningful projects using Rails.
People complain about the tech, but I would rather have a bad tech stack on a product/app with a chance than the perfect tech stack making the next twitter for dogs.
P.s.: Just take a look at how this article is exploding (also most of the other Rails articles on Hacker News lately). They don’t just explode in popularity and comments but every single one of them has given me ridiculous amounts of karma. I would say that is a heavy indicator of a Rails popularity bounce-back, vocal AND silent.
(JavaScript is a bit of an oddity since it has a formal language spec, but NOT a formal virtual machine spec.)
If I started a project today that was slated to be on the web, I'd pick one of two languages. If the least interesting part of the work was the code, and I didn't see significant places where I was worried about future performance in the business logic layer, I'd pick rails. (This is 95% of cases.) If I thought this system would have performance-critical components or would need to scale to thousands of programmers of varying skill, I'd pick java.
(I have a soft spot in my heart for clojure and elixir, and there are some edge cases where I might pick those, and a java ecosystem would allow for clojure interop. For example, some problems lend themselves to functional thinking. And, of course, there are some problems where another language shines - I could see defaulting to another tool if necessary.)
Look at the people in this comment section that are emotionally upset that the author didn’t prefer JS over ruby. They’re calling the author stupid, saying the author is bad at bootstrapping or just not using the right frameworks.
People don’t seem to be emotionally connected to Rails in the same way.
New Rails with turbo streams is great, but often times it's desirable to do data processing on the client, and then getting back to JS feels like a step down.
If yes, what was your opinion? I never tried it since I'd rather just work in two languages.
You could use one of many project bootstrapping tools to quickly spin up web applications in Node, Go, or Rust.
If you still insist on using a dynamic language, then at least try the Phoenix framework in Elixir. It offers so many more good ideas.
The performance degradation for 99% of web app use cases is negligible compared to the productivity increases. My team switched from a node/react environment to a full stack rails monolith with stimulusjs and we're shipping faster with less bugs.
What do you consider "too much magic"?
>I’ve always found it hard to climb out of the plumbing, forget about it.
This is the crux it of it, and it's true for any web project not relying on "magic" frameworks. And of course, it comes with tradeoffs. Namely, frameworks can be inflexible, and they can be difficult to understand/debug under the hood.
There is no escaping these tradeoffs, with any framework or language. More magic means less plumbing and more initial speed, but less flexibility and potential issues as complexity/scale increases. It's all about trying to choose the best tool for the job.
From my experience with Rails and Node, I could not believe a Node framework, e.g. Nestjs takes 5x more effort than Rails (nothing against Rails, it's a perfectly fine choice today for projects).
node 15
python 15
java 2
C++ 1
Java 2
ruby 2
go 1
elixir 1
What's popular is not necessarily what's right for the project.
Edit: I've noticed at the bottom the author mentions that they use "Node" to mean Node web frameworks, but still I think there's something lost to not mention the new wave of frameworks like Next and Svelte Kit.
This makes it trivial to write awesome web apps that don't need any JS on the client to work. Of course if JS is enabled client side you can do a lot more but this way the app is good to go without needing to parse any client side JS.
All data can easily be fetched on the server and passed down to the client for any route.
Is this Rails version still a monolith? Because the way Web3 is trending and with decentralization, microservices should remain the dominant architecture.
I built the site I'm currently working on in Python (Flask) based purely on the fact that I knew it best.
I've been toying with the idea of adding a React/Vue frontend for months but I can't bring myself to do it because, well, it's complicated. I barely know where to start.
It's not a 1:1 comparison to Rails (I'd love to try it someday), but I feel a lot of what the author is talking about. Boring, well developed, well proven tech makes rapid featured development a breeze.
MVC all the way, because otherwise you're never going to finish it. Doing a separate backend + SPA is an insane amount of work compared to a traditional full stack framework. Just thinking about validations (both server and client) make my brain hurt. Also you'll have to rewrite the frontend before even finishing it given how fast the landscape changes.
And even being a small team and not just yourself, I'd only think of an SPA if 1) You need an offline first experience, or 2) You don't have full stack engineers at hand and you only have backend people which don't want to touch JavaScript and frontend people which only want to work with JavaScript..... but this is more of a people problem than technical one.
I've done a lot of Django in the past, then a lot of SPAs for the last 6 ~ 8 years, and now I'm back to Laravel + Livewire and I'm living in a dream right now. Everything is so easy that I feel I've been cheated the last few years.... so much time and money (from my employers) wasted...
I bet rails is very productive. But getting a SSR hello world up with Node should take two minutes. Express, EJS, done. Most of the admin pages on fastcomments are server rendered and we add features pretty quickly (IMO).
If one has a requirements shift, and is told to integrate some other prior art, then deep exptertise on both the language and the framework are needful.
That is: the silver bullet is mainly available at the gun range.
> Building the web app in Rails took me 2 days – the same thing in Node would have taken 2 weeks
This is ridiculous, you are comparing a language framework with a runtime. Anyway, my problem with rails and other template based server side rendered frameworks is that the output looks decidedly un-modern and extending it to add the interactivity you can get from modern JS frameworks is hard. I have worked with code bases that were django or rails that bolted on react and other javascript frameworks and the result was not pretty.
For my personal projects today what I do is the following, I use nextjs to build the frontend and I use nestjs with prisma for the api (a lot of the plumbing you were talking about is autogenerated here). I probably can't get up and running in 2 days but I can do it in under a week and adding new features is painless.
> the output looks decidedly un-modern
You could say that about anything. The output styles to how you style it.
Also since when is modernness more important than content?
Design is just as important as content. Design in terms of how nice the site looks and design in terms of ux and usability. If people ignore your site because it looks cheap then the content is pointless. Most users really expect SPAs, they don't expect having to reload the entire site to see new content.
Then you get into usability and many react component libraries really work well with you there. Accessibility for the visually impaired is baked into the library and the popular libraries follow modern UI conventions.
It's really quite amazing what you can do now with these HTML focused frameworks.
I recently had to quickly add a front end feature that really should have been a separate web app to my main project at work (Vue SPA) to get ahead of some external audit.
Another team hastily built the back end + rest api. There's no filtering / pagination / anything nice in the api, so we just get back 1000s of records and do it all on the front end.
Found out prod deployment that it's used exclusively by contractors in India on very low power VDIs. So extremely bad performance. Doing it literally any other way would have probably been better, but something like LiveView would have been great for the interactivity. Although I don't want to go back to a world without static types.
Give me templated HTML any day of the week please :)
I learned it and started developing this way taking separation of concerns as dogma and now I look back and wonder why we ever did it that way.
Mixing your JS/Other Language/CSS/HTML into components is a separation of concerns that really matters: separation of business/application concerns. Having everything you need that works together to solve a problem in place is very powerful (not to mention convenient).
It's clean, clear-cut, easy for IDE's to parse, and everything is in its place.
Dogma or not I still prefer everything in its place vs trying to watch my IDE twist itself in knots trying to figure out which language to use for a given context. To say nothing of all the little eccentricities in the JS engines' reimplemented parsers.
In practice nothing works out like this. JS and HTML are tightly coupled, the frontend ends up needing to enforce business logic as well for usability reasons, etc.
> trying to watch my IDE twist itself in knots trying to figure out which language to use for a given context
This is not an actual issue.
It does and can. Sorry your team sucks
> This is not an actual issue.
Yes, it is. Why would I bring it up if it wasn't?
My team doesn't suck I work with some of the best in the business.
> Why would I bring it up if it wasn't?
No idea, I say it's not an issue because it's not. Millions of people work in react with typescript and have 0 issue working with html, javascript, and css in one ide. I didn't have to put in a lot of effort to configure my IDE either. So this idea that ides can't handle this workload is completely bogus and you are lying though your teeth or just ignorant.
And if some of the best in the business can't (or won't) keep separation of concerns, then I can't help but chuckle to myself at the mess they're creating.
How many levels of metaprogramming do you have to do? Most IDEs start to falter around the third or so. I've been assigned to shit that is Ruby writing HTML containing Javascript writing even more HTML in React's bullshit not-HTML dialect. And yes my IDE chokes. And if that project's designers weren't fucking insane it wouldn't have to, but I digress because modern tooling is a fucking joke. Typescript... pah. Crutches for people who suck at JS.
Besides, the "best in the business" are out there writing embedded C code or zerodays or format codecs. Not writing web apps
Reddit is not 'real time' app, and this seems like a feature, not a bug. Slack is way beyond where Campfire started out, but can you boil the difference down to interactivity?
In my experience, speed matters the most. Not just of development, but in user-experience. Rails is pretty damn good at this, especially recently. I still can't believe how fast a big Rails site like dev.to loads.
JavaScript is much harder to avoid because there's isn't really a native alternative in the browser. JavaScript is forced down our throats, liking it or not.
So yes, I personally resent js and its community for it. And I feel extremely pissed when I'm told how supposedly awesome this technology is, because I'm having an indigestion. It's not about getting a rise out of bashing, it's just the expression of an immense fatigue about this ubiquitous stack.
So there's the light trolling of other stacks, and there's js. :)
I'm an entrepreneur of sorts so there are stuff that I can't really avoid because no one else will do them for me. Doing frontend work is part of that list. I also do a bit of "devops" freelancing and it's hard to avoid to have to fiddle with npm there as well. The size of the part of the industry where you can avoid js is shrinking by the day
For example (in a parallel but similar universe to ruby) you have python, django and vast sea of data science / machine learning "plugins" you can just pull into your project.
Add to that that the idea of creating "desktop like" experiences in the browser seems to go against the grain of what the web is and we may indeed have reached "peak javascript"
Maybe the success of vue and the emergence of htmx point to this underlying reality
Sure you can build a database like H2 in C++ and yes doing so will take ages which I think is why most people don't do that and just use MySQL instead of reinventing the wheel. Does this mean we should switch from C++ to H2? Obviously not, what am I missing?
Wouldn't a more useful comparison be something like Node vs Ruby or Rails vs Sails
Are there any node.js based framework that has similar productivity speed with Rails?
Sveltekit uses an intuitive file based routing system, so for side projects at least, you can build out an app/POC very quickly.
Personally, I like Sveltekit's back end server better than Rails (to be fair, I haven't used Rails heavily since v3/v4) and Express. Having said that, I'm not sure Sveltekit's node adapter has been proven to scale yet.
Rails has a lot of nice stuff baked in though. So in terms of the many other moving parts of making an app, such as migrations, db connectivity, I think that's where a lot of time can be added on the Node side, especially if you don't already have a shortlist of go-to libraries for the core functionality you want/need.
the weird part about this post is it compares a framework to a runtime. that's weird and dishonest. a more realistic comparison is ruby to javascript.
I'd prefer Spring, Quarkus, or Micronaut with Kotlin, because I think these frameworks have better APIs and the performance is better. I also enjoy static typing with a modern language like Kotlin.
Laravel:
- no admin (although there are good free projects like filament admin)
- not well defined models
+ queues builtin
+ task scheduling builtin
+ livewire builtin
+ webpack builtin (this saves a ton of time as if you have a problem someone else likely has had it as well)
+ builtin relatively sane api framework (although the inertia integration for things like Vue, seems to almost encourage exposing more data than you mean to, I see this a potential data leak vector with unexperienced developers)
+ composer is way better than poetry/pip/pipenv/ whatever
+ first party support for many things you'll need (Payments, Browser testing, Hosting, Docker development, etc)
+ cheaper developers
+ Laravels facades such as Collection, Arr, Str remove many of the warts of PHP and in some cases can make some manipulations almost as concise and readable as Python
+ Laravel seems to monetize things better which imo is a path to sustainability.
+ Encourages use of modern css frameworks / javascript frontends.
Django:
+ admin (although dated looking and very hard to sell for client facing admin stuff, as it will never look like they want it to), honestly maybe the best admin out there for speed of setting up etc.
+ better models with db columns defined in model, could use typing though.
+ way better documentation
+ python's better more concise syntax on most things
+ fully automatic migrations (although you will eventually run into issues here, with good practices can work very well)
- python packaging in a horrible state
- too many basically essential packages not in core (api, queues (even database based queues))
+ python packages for basically anything out there somewhere
- Django rest framework (this project was okay for its time, but it is seriously dated, and takes the air out of some better projects such as django-ninja)
I'd also add Django is great if you're building only a backend with it (and you have no frontend and/or it's an external SPA).
For full stack development, Laravel all the way. Just it's templating system (blade) is a joy to use compared to Django's templating system which feels stuck in the 90s.
Node.js isn't easier but it's more useful in practice IMO.
Learn Next.js after sinatra/express and you are good for 80% of jobs.
I think Rails would be comparable to something like NestJS in node. Probably it will take both 2 days? However different experience for sure.
This issue is not about choosing RoR vs NodeJS, this is about Framework Vs Libraries or more technically speaking being lazy and choosing what other people say Vs doing proper research what best suits your project needs.
Rails with Hotwired seems to be the ultimate one person framework DHH wrote about today - https://world.hey.com/dhh/the-one-person-framework-711e6318.
Really want to try and use Rails for future projects but the magic is just too much for someone new to Ruby/Rails. I had to rewrite the routes with brackets in Rails to understand the working.
rails doesn’t cope with that issue very well (some suggest a command or strategy pattern, others service objects, etc.), which is one of the only major criticisms i have with rails. node/npm dependency was another big criticism, but they’re fixing that with rails 7. =)
+ Less Magic
+ Better Migrations
+ Better ORM
+ Django Rest Framework
+ Admin Interface
+ Great Documentation
- Less Packages
- Python package management (a raging dumpster fire)
Ruby settled on a two-part solution, Rubygems and Bundler, over a decade ago. One is the package format, hosting server, and default distribution, the other is dependency management. In practice they are two sides of the same coin, and you don't have to give much thought to them. I hate reading reductive "It just works!" quips, but it really does apply here.
On the Python side I think the movement has started to fix the packaging mess. It's going to take a while me thinks.
> On the Python side I think the movement has started to fix the packaging mess. It's going to take a while me thinks.
I hope you are right, but ... this is the pattern: every year or two someone decides to fix it, goes about 80% of the way to a complete solution (which is maybe 50% of the effort, of course), that becomes 'the thing to use'. But then it is abandoned because that last 20% of functionality is a lot of work, and someone else comes up with a new shiny thing, and the cycle starts again.
Not holding my breath, in other words.
That's basically the same instructions you will have for ruby and javascript. Ruby package management is about as good as python's, while javascript is a toxic wasteland.
There are languages with better dependency management, and languages with worse ones (ok, not worse than javascript, no dependency management is still better than javascript). But python and ruby do not have much difference.
Yeah there's less magic I give you that, but also because it does much less.
Also for me the Python packages are a minus, they are usually not tested very well and it's very easy to burn yourself when migrating (good luck finding some equivalent of rspec)
That was probably only true 6–10 years ago. Migrations are a solved problem in Django and I can only think of one very obscure query that I couldn't get done in the ORM and had to drop into raw SQL. Aggregations, annotations and other query expressions in general have lifted the ORM to a truly strong position
Where are my scopes? Where's the equivalent of strong_migrations? The equivalent of db_consistency? Where are delegate attributes? Concerns? Arel?
The ORM isn't bad I'll admit that but some complex features are tedious.
I've never used rspec but it sounds like pytest and hypothesis would do the job. In ruby there's no hope for pytorch / tensorflow / ray / numba.
Sorry it really does not, having factorybot + rspec + rspec-mocks really is a super power when it comes in testing.
The issue is that most of the time I land on a django project, it has really poor testing whereas most of the time I land on a Rails project, it has very close to complete testing. The reason is that the tests are more tedious to write.
And this culture trickles down to your dependencies as well. Anything you install with rails is almost guaranteed to have the upmost quality of testing.
Have a look on the examples here https://github.com/rspec/rspec-mocks
Rails is a Web Framework. I don't understand the point about ML. Those categories are totally different. I guess it might be a tiny plus, but not very practical. Going this route one might conclude that game studios should build Websites in C++?
pytorch: https://github.com/ankane/torch.rb Tensorflow: https://github.com/ankane/tensorflow-ruby
Still, no information how they are better than the migrations in Rails?
We usually also want the “magic”.
I can’t argue with you about the ORM and Migrations since I haven’t used Django much. The feeling I get though comparing the two is that Django is more fixated on building business facing backends and Rails is more focused on building customer facing frontends.
Over all I would recommend figuring out if you are more of a Python/Django of Ruby/Rails type. It will tell you something about your personality.
As far as getting things done, well its probably the best admin site out there.
> Over all I would recommend figuring out if you are more of a Python/Django of Ruby/Rails type. It will tell you something about your personality.
That's a great insight and probably very true.
It is sort of sad but understandable.
That's why I usually don’t go with an admin framework like ActiveAdmin in Rails. It isn’t that hard to build some general functionality for the admin interface. And the admin interface frameworks I’ve worked with in rails where hell when you needed something special and in my experience there are always a lot of special cases.
Sure you get a less consistent interface and you can argue about how much more work you have to put in to the admin interface when compared to using a gem but you can shut up the customer request quickly and just move on with the none bikeshedding part of the work.
The migration framework just works, I can't really compare it to rails because I haven't used rails in a long time.
DRF seems much more fully featured than rails-api, it comes with a browsable API and OpenAPI integration.
Again I don't mean to trash on Rails, it's a great framework and miles ahead of anything you'd find in the nodejs ecosystem.
The question I was replying to was "What does Django offer that you feel is an improvement over Rails?" and I tried to answer it.
I wouldn't say that the ORM is better (in fact both ORMs are bad), but the way it integrates with everything is just awesome.
- Terrible templating system
- No equivalent to hotwire/livewire/liveview
- No built in jobs/scheduling system
- Insanely bad packaging and dependencies system
Deploying was also hell.
But it was fast, stable and once you solve a problem it is solved 100% .
Its frontend solution is a 90s monty python's joke.
Rails, Laravel, etc are real full stack frameworks.
Going forward we are writing new parts of the system in other stacks partly as a hedge against the impossibility of hiring for Rails.