I Miss Rails
chanind.github.io
chanind.github.io
You're in luck. Rails 5.2.3 was released 20 hours ago.
More seriously, I feel rails is still excellent and I'm happy to work with it every day. I'd be interested to hear more about what makes rails not modern? I find it a very productive framework.
EDIT: If you're talking about missing a JS equivalent of rails, do you know about Loopback? https://loopback.io/
https://groups.google.com/d/msg/django-developers/mLlWYEC8_G...
And with django-channels (https://channels.readthedocs.io/) Django goes way beyond just WebSockets. You can now do fully asynchronous data processing pipelines.
I'm still happy working with Django (which is not something I can say about the JS ecosystem). Especially when doing APIs with Django REST Framework.
Channels was supposed to make core but never did - what happened there? That's what I was driving at really - if I were stewarding a modern web framework, I would be integrating websocket support. It never sat right with me that something as common as APIs is farmed out to a library in Django (this comes out of the box in Rails with no configuration) either.
I don't dislike Django, but I certainly find that there's a lot more messing around to get done things that I would consider pretty standard. I used the new Rails beta last week and I noticed that Webpack integration is now there - how long until we see something like that with Django?
https://www.djangoproject.com/weblog/2016/sep/09/channels-ad...
This async support is hopefully coming within 2019. I'm super-excited about using it in future django projects.
In short, the efforts are constantly undermanned, leading to developer burnout. Andrew had since came back to pushing things (ASGI 3.0 came out last week), but it seems like he intends to focus more on the big picture (standardise async web stuff in Python) than spending time on Django specifically.
Step up if you believe you have good visions on making Django a “modern web framework”.
For instance, the posix IPC implementation of ASGI is very buggy and "not officially supported". The other implementation uses Redis (so, yet another component to take care of) and is quite brittle as well. We've noticed severe slowdowns of downloading images when using the Daphne web server in development mode, many issues running out of memory, clogged queues and so on. This is also very difficult to debug, due to the many moving parts, and of course it only happens on production, so good luck trying to reproduce it locally.
For this project (which is still in production), we ended up falling back to a standard Gunicorn web server setup using traditional WSGI to handle regular HTTP traffic, and relying on channels only for websockets. For new projects, we've moved to a tiny standalone gevent-based websockets server (https://pypi.org/project/high-templar/) which we deploy next to a standard gunicorn stack. It is much simpler and much more stable. Unfortunately, it's something we've developed in-house, so if there are issues we have to fix them ourselves. There've been some problems with gevent which apparently have been fixed in the latest git repo, but there hasn't been a release since last year. So many issues....
I’m concerned about performance. As much as I know that premature optimization is the Devil, it’s hard to stomach deploying something that is so notorious for becoming a bottleneck. Once I get past my MVP of this feature and have some maintenance hours budgeted, I plan on exploring AnyCable.
Symfony 4 however is wonderful, they modularised everything, kept backwards compatibility, properly deprecate things and it's fast, like really fast.
Yes they don't follow semver but a modified version of paradigm.major.minor
Lazy loading in Rails tends to refer to how Active Record waits until access time to send the query: https://rubyinrails.com/2014/01/08/what-is-lazy-loading-in-r...
It's still synchronous.
Both do quite a bit better for cleanliness and setup time than any of the other platforms I’ve used for web development.
...WHY would anyone ever want that?! I thought that splitting an app into one frontend-app and one backend-app, each in its separate repository too and runable alone is the very minimum everyone does nowadays.
(Yeah, later you may go on and chop the backend into microservices, but for starters you at least keep these two sepratate - why would you want to impose knowledge of Python or Django as requirement for your frontend developers?! Even if you start with a couple full-stackers, you'll want to later be able to hire more narrow focused specialists.)
It depends on how big your project is. If you only have one developer it's fine to have to it tightly integrated.
Given the insecurity without huge token authorization, I'm not entirely surprised.
They can try again when they figure out encrypted and variable token creation.
> added no value
It gives you an API explorer, routing, ORM, validation, error normalization, authentication, authorization via ACL, and more out-of-the-box. I'd consider this value.
> had lots of obvious vulnerabilities
I'd like to know more about this. The only thing I can think of is bypassing ACLs via fetching records and including relationships. I don't know of any framework or combination of libraries that doesn't have this vulnerability.
> LoopBack 3 was terrible - complicated
This is probably true. LoopBack 3 essentially uses a single model to represent your API and data model. This is the single responsibility principle taken to the extreme opposite. It's a complete nightmare at times. If you have an exact one-to-one mapping of your API to database, this may not be a problem.
> unless the entire team and philosophy behind it has been replaced
Loopback 4 seems to be the same team, but I believe they have learned a lesson on coupling. https://loopback.io/doc/en/lb4/Crafting-LoopBack-4.html
> Models are overloaded with multiple responsibilities, such as data representation, persistence, and mapping to REST.
They have a way to go to reach feature parity with LB3: https://github.com/strongloop/loopback-next/issues/1920.
BTW, I also miss Rails.
Not that i don't know how to write SQL queries by hand, it's just raw SQL queries with conditions is just ugly.
Unless there have been some major changes I highly advise staying away from sails.js.
I work on a hybrid React-on-Rails application and working on the React portions is so. fucking. painful. Seriously the shit people come up with with this "tool" makes corporate-hack Java programmers look good. I am always taking the backend Rails-y tickets if I have the chance
This is not to say that JS is shit but both JS and Rails have their place. If you want flexibility, you need JS. If you want iteration speed and dev productivity you need Rails.
From this hot take on JS, I'd think people are suggesting that the development experience of all the other available clients are a lot better, but then I became an Android and iOS developer and that's not true either.
Swift isn't bad, but the language isn't the only thing that dictates how hard client development is. I'd rather use React than UIKit abstractions, that's for sure. And CoreData is probably the worst and most outdated abstraction I've used across all platforms. And even if I think iOS development is the ideal way to write software... it only runs on iPhones and iPads.
I mean, of course the Rails side of your application is probably nicer than the client side where you get to stay in your simple request -> response realm that runs on the same machine. If given the option, I bet almost every HNer would rather be the person paid the same to build the API endpoints vs the crapshoot that is client and UI development.
But I see this perpetually confused as Javascript vs <my favorite language I use on the server>. For example, Ruby fares pretty poorly against Node if you forget the client, like Sinatra vs Express/Koa.
When you make a jump to a JS stack (whether client side or server side) you have a lot of options but no best practices or conventions to follow. You have to make a lot of choices which have already been made for you in RoR. Even though SPA frontend dev has settled between React and Vue, you still have to make a lot of decisions. React also bills itself as a view library. You have to make decisions about state management (if needed), routing etc etc. A vast chunk of these decisions are made for you in RoR so that you just work on the app. I think this is what the author was lamenting about.
These days I prefer building something up from microframeworks and I like to take the opposite side of the trade-offs you mention in your comment. There are a lot of aspects of Rails I ended up really disliking over time.
But at the same time, I still find myself thinking back to some of the pleasantries that Rails gives you and wishing I had them in my bespoke applications. Even just things like being able to enumerate your routes from the CLI or seeing your SQL queries and query response time in the terminal during development. If it's something you have to implement yourself, you just tend to not do it at all. And there's a lot a framework can do for you with some opinionatedness.
I think the classic example of this realization is when you deep dive on microframeworks, accumulate them in production, and encounter things like performance issues but realize you don't even have the tools to debug them because you didn't build them.
If the platform is too unopinionated you will generally wind up with: 1) A project with many competing ideas (most js projects I see end up like this) Or 2) A team with some people feeling like they are not heard
Not true at all. Rails can be extremely flexible; it's all modular and you can reduce it down to almost nothing if you want. Javascript's only place is to run in the browser; it lost its way once people decided to make a server platform out of it. JS is far too forgiving of mistakes to be running backend code, full stop. ES6 and up are vast improvements but the damage has already been done.
And in any case I have yet to work in an environment where I am not writing at least some ES5...
js and ruby were released in 1995, with rails coming 10 years later. so js development wasn’t fast in the least. after the little ajax blip resulting from outlook web access’s release in 98, js stagnated until node came along and made it interesting again.
prototype/jquery a little before it and later front-end frameworks like backbone, ember and then angular helped cement js as a thing. it only seems fast and wild because the ecosystem really only woke up again in the 2010s.
(i tooled around with js on netscape right after it came out but then lost interest)
while gmail brought a nicer ui/ux, i still credit ms owa for showing the world what js could be when it grew up.
For me, the more interesting question in all of this is where did this fervour for JS-and-the-way-down actually come from?
My hypothesis is that it's the natural result of a huge mess of new talent - fresh out of various overpriced Bootcamps and told that their 9-week educations give them a credible opinion in true post-modernist fashion - all being released on the world at the precise moment that a predictable police lineup of over-promised technologies were all at the top of their respective hype cycles.
Humans have a predictable tendency to assume that the thing they are thinking about at the moment is far more important than it actually is. If you have a very short institutional memory and everyone you know in your bubble has been programming for a relatively short period of time, pretty soon you can start to believe that if everyone is doing it, you couldn't all be wrong.
For me, the most compelling example of progress coming from the JS camp was my shallow investigation of the Expo platform for React Native. It has some genuinely sexy developer ergonomics features which I'd love to see make their way back into Rails.
Hartl is great, has his/its place etc. Sometimes you just need a smart person with experience to add personal context. Happy to be of service.
This community is full of experienced professionals who use Javascript even in the face of alternative options, and we belabor this topic every day.
So what excuse do you have for assuming and hypothesizing that everyone must be an unenlightened boot camp amateur when you could've turned to anyone and simply asked?
For example, to me, modern JS is not substantially worse than other dynamically typed languages. Give me Python and Ruby code and the Javascript version probably looks the exact same. Meanwhile, those languages don't have a 1:1 version of `results = await Promise.map(urls, (url) => crawl(url), { concurrency: 8 })`. And that's not to start a language war but rather to demonstrate a concise example of a technical strength, aka a purely technical ground that a craftsperson could reach for that tool.
But now fold in its advantages like ubiquity, async-everything, runs natively in the browser, and has a static-typing system that's actually catching on, and it should be pretty obvious why someone could pick it when given an option beyond "they don't know any better."
Also, there's the obvious trade-off of treating your server as the API for all of your clients and treating the web as just another client that runs on the user's device instead of essentially coupling it with the server.
But surely these things are obvious or easy to find out, so it's hard to assume good faith in your post.
I assume you meant to instead draw a distinction between a large framework like Rails and a tiny one like Sinatra. And I'd say that ranges from a matter of taste to the composition of your team more than anything else. Obviously there are upsides and downsides to any point you can mark on the continuum.
But you're right that I made an invalid comparison to React. It's more the starting with Node and having to add a bunch of functionality that you would get out of the box in Rails, because a front-end framework like React is the preference, and lots of developers would rather write isomorphic apps/sites.
Concurrency in this situation almost becomes free at the expense of changing
user = db.findUser(42)
to user = await db.findUser(42)
So when writing programs where you want more than one I/O thing to be happening at a time whether it's network requests or a bunch of concurrent workers, which is pretty much why you'd use Node, you get it trivially.Even something like running parallel DB queries trivially inside an Express route:
const [a, b] = Promise.all([db.findUser(42), db.somethingElse()])
Or starting one async early, waiting on another, and then ensuring that the first async thing is done later on: const a = runA() // returns a promise
const b = await runB()
return [a, await b]
And once again I think this is the a great example of a useful abstraction when writing anything with an I/O boundary: const results = await all(urls, url => crawler(url), { concurrency: 8 })
That code in Go would take me 40 lines and involve wait groups.Compare that to Netty or trying to write async code in Rust where it's really easy to block the event loop because all libraries and stdlib are sync by default. So you're passing around a CPU pool to run sync code inside your async context. It's hard to look at that sort of code and understand its runtime behavior. Oops, you accidentally blocked. Oops, the pool gets saturated immediately and starts blocking. It's hard to straddle both worlds, and the code is constantly trying to "return to its sync default" so you have to be eternally vigilant. Sync isn't necessarily the default you want, either.
Of course, this comes with other expenses like needing to run one process per core and you can't do CPU-bound work in-process. But you may be used to that limitation using Ruby or Python for example.
I'm not trying to start a language war or tell you that you should drop what you're doing to use Node because it's The Best.
What I'm responding to is this idea that you couldn't possibly have a technical reason to use Node given a choice unless you're fresh out of a boot camp and know no better.
However, you are (perhaps unintentionally) twisting my words. I brought up bootcamps because I can demonstrate a strong causal association on a timeline.
The beef, such as it is, is with the 750k npm packages, the brutal moving target that is the packaging/transpiling/dependency hell/OCD bikeshedding that comes with a commitment to the JS ecosystem. And given that you used to be a Rails user, you know full well what giving up sane defaults in favour of the pursuit of pure compositional bliss looks like, but you're choosing to forget the trauma.
Meanwhile, there's an entire generation of new devs that have been told that Rails (or your favourite server side alternative) have been eclipsed by better thinking. I don't think I'm just an angry old man screaming at cars from my porch when I call bullshit.
Meanwhile, there was once upon a time a perceived crisis of junior talent which led to the creation of the first code bootcamps, all of which were taught Rails, jQuery and Sass. I'm not trying to be shitty, classist or ageist in suggesting that the bootcamp phenomena suddenly started emitting a large number of blank-slate new devs that would understandably treat every exciting idea as the most incredible thing since <insert your fav noun>. After all, if you have few previous experiences, what can you compare against?
Previous generations of devs learned predominantly through either auto-didactic persistence or academic lectures; this new crop was suddenly predominantly learning from (and influencing) each other.
I recently read an excellent book called The Death of Truth, which technically has nothing to do with programming... except that in this conversation, it's totally about programming. If every coder's ideas are treated as equally valid truths even though there exists a massive gulf between their relative experiences, then we're confusing feelings with good engineering.
It's not perfect by any means, but I think it shows the shape of things to come.
I'd be really interested in a typescript like superset of ruby, and I've even thought about building a prototype of it, though it's quite outside my area of expertise.
But I don't know why you'd say that. ActiveRecord models are one of the main places you'll see a bunch of `use SomeGem::Thing` that introduce a bunch of magic methods on model instances.
And my point is that we aren't talking about method composition here that you can statically analyze with a bolted-on type system. Ruby's metaprogramming runs so deep that it's a substantially bigger challenge than other dynamically-typed languages.
One clue is that humans even have a hard time with it. The first shock that people have with Ruby is when you see a method or identifier and grep shows up with zero results.
Aside, I can kinda tell that Ruby is entering Perl territory when there are no beginners around to chime in with their gripes.
We had a discussion about Ruby's type annotations 4 years ago at https://news.ycombinator.com/item?id=9481186
I found it by googling the status of the work on Ruby 3 type annotations. The top comment is mine and I still agree with the past myself.
https://github.com/ChangJoo-Park/amber-realworld-example-app...
(I couldn't find any code snippets on the official Amber framework page, I hope this is representative.)
This week I’ve been porting one of my Spring Boot apps to Kotlin and that was a great experience.
The only thing I’m waiting for is good reactive drivers for Postgres and then you can go with their new reactor based apis instead of the older one-thread per request Spring MVC.
Some API's are adapted to take advantage of modern Java features like for example JPA repositories that can return Optional<T> for single row queries and Stream<T> for multi row queries. Some API's have been improved with functional equivalents.
If you combine this with Kotlin you get all the power of the Spring framework together with excellent nullability checks and modern language features that Kotlin brings to the table.
Stripe have been working on a type-checker. No idea when they're going to release it to the public though.
(but yeah, ActionCable was a no-go. We use Pusher instead)
That attitude needs to get out of everyone's head. You are the tech industry. If you want to build something in Rails, a mature and capable framework that has tons of support and won't go away, just do it. Who's going to stop you? Applies to any other technology that's stable as well.
So, Python has the ton of data science libraries, and it also happens to have Django...
Where would people recommend I read about (a) getting up and running with rails 5 and (b) appreciating what's new and improved in the last 8 years?
No need to "bundle exec" anymore, because simply cd'ing in and out of project folders resets your gems to a clean list only required by that app. It's great. The years come and go and I still hear people complaining about Ruby version and gem hell and I wonder why the heck they aren't using RVM!
I would not go down that route, because at least Loopback 3 looks promising at first, but after a while it does not scale dx-wise. The biggest trap my team fell into, was that you could „include“ related models in a request, that you did not have permissions to. Media management was also very poor and did not integrate well into the whole eco system.
We are now using TypeORM[1] and routing-controllers[2] which has been very nice so far. I have been building my own framework at work on top of these and it safed us a good chunk of time. If you want to have a look, go to my profile, I have put a link there.
[1] https://typeorm.io [2] https://github.com/typestack/routing-controllers
The whole thing he explains in the post: he wants an all-rounder like Rails but which covers the SPA/JS side.
For folks here doing startups, imagine the speed boost of maintaining one less entire application than your competitors.
Everything more than that just feels to much like having multiple code bases.
But I suppose that DHH got burned with Prototype and then CoffeeScript and wouldn't endorse something like this.
Server-rendered used to mean slow and clunky but I've found that using Go my page loads are super fast. The inter-page transitions can sting a little on really really slow connections, it's true. But users are much more willing to deal with them if they haven't first been subjected to a minutes-long spinner while the SPA loads up all its libraries and state.
A little game I sometimes play is asking fellow developers to try and guess the frontend framework used on one of my apps. They click around for a little while wondering "Angular or React" before I tell them it's actually just some Go templates rendered on the server. It often opens their eyes that the loads were so fast they couldn't actually tell they were happening.
SPAs have their place and I've written a lot of them. It's amazing how far you can take server rendering in 2019, though.
I'm all for server side rendering - I maintained several vanilla PHP/HTML/CSS websites in the 2000s, and only used jQuery sparingly when things grew in complexity. I later used Django for many years similarly, and when react/ember/angular/etc. started blowing up is when I started feeling like performance was something we had to worry more about.
That being said, server side rendering shows its limits when you build an application with lots of actions your users can perform on the data shown in their window, and reloading the page every time would significantly slow them down. That's when you're tempted to start going the SPA route, but those frameworks tend to be pretty opinionated about how you should structure your code and data, a slippery slope that leads to the stereotypical bloated, unresponsive JavaScript mess some websites have become famous for.
There is certainly a balance to be found, but it's a tricky one.
For autocompletion, datepickers, etc I use drop-in components. These tend to be jQuery based but it's not the end of the world.
When I do have a particular view or flow that outgrows the "bits and pieces of JS" phase it's actually pretty straightforward to use a modern UI library like React or Elm on that view alone. Reducing the scope of the area you're using the framework in rather than writing the entire app in it simplifies things pretty dramatically. The JS doesn't need to worry about routing, pushState, etc etc etc. It just deals with its own little patch of DOM and state.
There was a standard (https://tools.ietf.org/html/rfc3229) to diff pages so that only the delta would be sent to the browser. After that the only missing piece would have been that the browser doesn't refresh the whole page but intelligently re-renders the difference in the DOM, and that would have been the perfect world.
Of course, this is just wholesale replacing a DOM subtree with another. But there's also probably some point where just parsing the new subtree is faster than attempting to create and apply a diff.
I find that once a company uses the product, they never stop. The customer base is very sticky.
I have also found that I bounce a lot of companies that don't "get it". They don't understand that it's about making things better for candidates and so all they see is Hackerrank with less features.
My challenge for growth is finding better ways to explain the ethos and the benefits to those companies.
I don't get why everyone keeps saying this. Is it because of WordPress? In 2005 I used my own MVC framework with ORM and stuff. It was written in PHP. My pages had the usual generation time of 0.03 seconds. And that was with no specialized caching or any crazy optimizations. Even with no AJAX, page loading seemed instant, unless you connected to the server from across the world.
one nit pick, what does "server-side rendering", and even "client-side rendering", even mean? The browser renders HTML, it's always client side and it's always outside of the scope of application code. Does "rendering" really mean template parsing?
This is an excellent point. Both HTML and JSON are string representations of data structures. Both are eventually transformed and converted to DOM.
It's kind of a misnomer; it usually means generating a "renderable" thing (e.g. HTML) , not actually rendering it on the screen because yes the browser does that.
Client side means the layouts, templates, partials, components are on the client and are stitched together their. The server only send data and the client app handles interpolation and generating the html.
It seems like the JS ecosystem changes so fast because it knows better is possible, so it just tries to reinvent itself over and over.
The JavaScript world starts with this weird prototype based language with a syntax that looks like it might be something more class based. From there it goes to dependency bundling hell, callback hell and Christmas tree code indenting, no standard implementation, and a library required for everything under the sun (Left-pad!) And somehow this is what the cool kids are into? I never liked Rails because it was "cool" I liked it because I love getting stuff done, fast.
It’s not perfect yet, but as a first version is remarkably capable already.
We as a profession seem to be perennial victims of availability bias.
We're naturally going to think of the stuff we've been reading about lately on the Internet first. Which is just never going to be the established and stable stuff that'll let you get your job done without producing any blog-worthy experiences in the process. "Went home after 8 hours without producing any fodder for war stories" doesn't make for an interesting tweet, let alone post on Medium.
What makes it order of magnitudes more performant than Ruby is that it's non-blocking, and now comes with a very pleasant syntax to accommodate.
Source for the "orders of magnitude" anywhere in the last year or so? Ruby with EventMachine outperformed Node significantly when I tested websocket chat servers.
One of the frequently overlooked properties of Javascript/Node is that it's async-everything.
I'd be curious to hear more about this benchmark.
But there are almost zero async-everything options in the space. And being confined to a second-class async subworld inside a synchronous ecosystem is a classic error-prone challenge whether you're using Twisted, Event Machine, Tokio, or Netty.
It's a pretty big downside of using Event Machine which even created its own networking primitives instead of using those in the Ruby stdlib.
I was talking about the general case of everything being async in JS. That's frequently touted as a benefit of JS, but it's utterly maddening to workaday web developers. You want your requests to be served async (which should just be handled by whatever framework you're using), but inside of a single request you mostly just want to write synchronous code, even when you're dealing with IO. It's a lot easier to reason about.
Consider the simple example of just running two unrelated database/network queries at the same time which is basically a ubiquitous desire when writing a web service:
const [user, stats] = await Promise.all([
db.getUser(42),
cache.fetchStats()
])
And now consider a case where you want to issue four database queries, but you don't want the route to take four connections out of the pool at once, instead ensuring that it only uses two: // This fn is built into Bluebird and trivial to find 8-line impl for.
// getA..getD are just functions that return promises so they can be
// created lazily.
const [a,b,c,d] = await Promise.map([getA, getB, getC, getD],
(fn) => fn(),
{ concurrency: 2 }
)
What I would simply assert is that these sorts of things are really nice to have in your toolbox when writing I/O code like a networked program, and I don't think there exists a simpler async abstraction for it than Node. And I certainly would not have said this until Node had promises and async/await.Does it tho? React, Webpack, Babel and TypeScript have been around for a while now, and I can't think about anything else more recent that had a similar impact on the JS ecosystem.
There are valid complaints to levy against the ecosystem, but the ones you listed are non-issues if you take time to learn the language and VMs/environments themselves. To be fair, I mean.
If we're being fair, what you say is true only if you are starting a greenfield project.
I don't use scaffolding [if I can help it]—unless it's some I've set up and maintain myself (if I know I'm going to do a run of similar projects).
Normally I only do greenfield projects as their architecture and maintainability are highest priority due to the need for longevity. Plus I often find those systems rather heavy-and not just in JS.
"The Rails 5 Way" (1088 pages)
"Ruby on Rails Tutorial: Learn Web Development with Rail" (816 pages)
Rails is enterprise.
Do we only use undiscovered indie frameworks now?
It has nothing to do with popularity being bad. In general that's good a thing, because support is better (and rails does have terrific support), but it does exert a feature-accretion force.
Orm is kind of a failure and requires us to write some queries by hand into string literals, but at least it has it's own sql syntax to avoid engine dependence.
I have lots of love for both. They're different tools. Ultimately I dropped Rails because being without static typing just isn't for me, but certain parts of the experience were positively magical.
I sort of feel the same way about Boot. That auto configuration mechanism is next level. The breadth and depth of what's available in the Spring ecosystem is great too.
They're really kind of optimized for different things though. Like Rails has some gems you just drop in and it blows you away what you get for stunningly little effort. But then it's not that customizable and you find yourself fighting with it. Spring has all kinds of battle tested enterprise grade bits and bobs that take a lot longer to operationalize but they'll last you forever.
I'm currently trying out aspnetboilerplate as a middle ground between the two. Specifically the aspnetzero version. It's like that "holy shit I get all this out of the box?" with Rails but the "I can understand this, work with it, customize it if I need to and it's going to last the distance". Im finding there is a slight learning curve to it and I wouldn't necessarily make all the same choices the framework does, but so far I can see this becoming a happy medium once I've found my groove with it.
But I think the key difference is Rails is more opinionated so you don't have to worry about which circuit breaker to use. Or just don't use any.
Spring was humongous and had so many modules that I just couldn't grasp the purpose of each (I still don't) plus there was a lot of overlapping functionality. Senior devs would come to college and ramble out stuff which made less and less sense as time passed by.
Writing a simple app became tedious without a reference by side. So that was enterprise in my mind - tedious, complicated and completely incoherent at times - what and why were completely skipped, at times, in favour of how.
At that time I discovered JS and the simplicity of assembling a decent sized app won me over. The startup ecosystem was also picking up pace in my country and speed of iteration mattered more than anything else. Granted JS can become a nightmare (which I learned later) but that speedy feedback compared to Java was enough to make node my "homestack."
There were other things which worked strongly against Java in my education - 1. Being forced to use eclipse without training (what are these buttons, what does everything do, how do i do this, I was fighting more against the IDE than anything else)
2. Being forced to use the Oracle database which was (for some xyz reason) given to us in a virtual machine and took ages to run a simple join in a small table of 100-500 records.
3. Programmers with experience can be completely oblivious to the mental model of a beginner.
All of this just soured me on "enterprise."
This is a great summary of much of the frustration of using Spring.
Start with Rails and optimize in Go for the services that get expensive to run in Rails, like https://gitlab.com/gitlab-org/gitaly
What's amazing, is I booted up a 4 year old project in minutes the other day at work. A co-worker was interested in using the project, it took 15 minutes to setup clean.
Overall, I find Rails is easily more maintainable and definitely enjoy it more than the Django and Flask apps I write regularly. Javascript (Node + React/Angular) breaks all the time when upgrading, so maintaining it is not super fun either...
Here's a project I wrote in Rails and deployed late last year:
Works like a charm!
I even recommend Rails to new people starting out because I think it sets best practices.
I definitely see the appeal of these frameworks, but I feel that a side effect of having them is that there's a metric ton of code generated and you really have no idea how it works. I remember spending almost 30 minutes digging through the C# object being used to parse JSON, generated by ASP.NET, to see why a field mapping was being done incorrectly, simply because I had traverse through four different files to see the logic.
Granted, part of the problem there is intrinsic to how C#/Java are structured, and the massive number of files needed by them, but I still feel that the code generation made it worse.
Even if the code weren't generated, the amount of ceremony to add an endpoint, add a new type to be parsed, and perform updates just does my head in. That aforementioned C# app was about ~1000 LOC, across a few dozen files. I rewrote the system, from scratch, using Clojure and http-kit in around 100 LOC, without losing any features.
I'm probably just old now, but I suppose I really dislike magic in my codebase, which is why I tend to prefer the lower-level things.
(Also, just a note, I'm a total hypocrite, since I actually wrote an MVC-ish framework in Node.js 5 years ago, then ported it over to Erlang).
I was reading the parent comment and some of the other comments about the mental model of a beginner. I suppose if you're first exposed to Rails and start using 'scaffold' it can generate a ton of code you'll need to grok. But once you understand the nuances of writing Rails its much faster and cleaner to just create files and go about your business. There is only 1 thing I ask Rails to generate for me and its database migrations; it handles adding the timestamp and placing it as the end of the folder, thats not something I care to think about myself.
I'm not opposed to libraries to handle a lot of stuff (like auth, crypto, and file I/O). I think it's typically irresponsible to reinvent these things for any reason other than "it's a fun personal project".
What I dislike about a lot of the frameworks is how locked-in I feel. There's (often) only one way to do things, and I don't always feel it's the best way, like my aforementioned parsing logic.
On top of that it prevents really bad coders from rolling their own in a really bad way. Remember when everybody was coding their own MVC framework in PHP?
As for C# not parsing JSON correctly, that seems more like a problem with a language or library not anything to do with frameworks?
It's not intrinsic to all frameworks I'm sure, but imposed structure like that does inherently lead to bureaucracy, which can make figuring stuff out difficult.
Then again not everything I work on has to do with web or API’s so maybe that colours things a bit for me.
I think I know exactly what you’re saying and I agree. Also no less the hypocrite here, but like WW said “I am large, I contain multitudes”!
With that said, might it also be possible that there could be some drawbacks? Having worked in and with Clojure, I found the ecosystem incredibly immature. It's somewhere beyond arrogant - reckless comes to mind - for most engineers to do all their own plumbing for a web service. The odds that they'll manage to design someone easily long-term maintainable are slim. The chances of authorization, authentication, potential SQL injection, and a thousand other security things being handled well is effectively none - the Clojure ecosystem seems wildly ignorant of such things. The core philosophy of just composing the libraries you need into Ring means that anything you don't actively think of will be entirely neglected. This is a dangerous and unprofessional way to ship code that will be facing the real internet.
This stands in stark contrast to the level of consideration around maintenance and security that has gone into a modern, mature framework. Or a modern language where SAST is an option.
Again, you're completely correct. Doing low-level stuff feels absolutely amazing! The sense of control, of having your hands in the guts and the ability to do what you need without wasting time on bullshit magic, is heady and glorious. It's just perhaps worth considering that that magic can sometimes be incredibly valuable, well worth the tradeoff against the feeling of freedom.
Is it perhaps possible that there might be some room to question if the goal of something that fits neatly it one person's head is really the best one? For professional applications, some might opine that there could be other considerations. Certainly most of my comments about Clojure apply to any tools that work from the same mindset.
But perhaps I merely misunderstand an elegantly made point of yours - can you help me?
I can see that there's probably a case to be made for "forced-best-practices", which a lot of frameworks kind of entail, and I think that if you don't trust yourself (or coworkers) to write quality code, then having the guardrails for that Rails and ASP.NET MVC give you probably feel nice.
However, I think a case can be made that these same guardrails can feel restrictive and noisy to more experienced developers (or people with large-enough egos like me). I have no desire to ever touch J2EE ever again in my life, no matter how much I could get paid doing it, because it felt like getting anything done was about as much fun as filing my taxes.
Rails is certainly not as terrible as J2EE, so I'm not trying to draw a direct equivalence, and maybe a balance can be struck...Personally, I find that the "give me a server and I'll set up some middleware on top" approach like Express (for Node), and the aforementioned Ring/HTTP-Kit for Clojure give me the best balance.
Clearly there's a middle-ground -- I certainly wouldn't suggest that most people go and reimplement TCP and HTTP from scratch for a project, unless they're severely masochistic, or they just want to learn more about TCP or HTTP.
[1] https://gitlab.com/tombert/frameworkeyPromiseEdition [2] https://gitlab.com/tombert/Frameworkey-Erlang
My takeaway from that is that it's unreasonable to expect even the best of developers to remember every detail every time. Even the best forget or make mistakes. If our tools don't take this into account and protect us from ourselves, we're going to get burned.
I just don't like having the libraries forced as part of the full structure, and instead would (typically) prefer them to be functions (or if you're in a Lisp, possibly macros).
But I don't know a better way to guard against all the things I might not think of. I've seen entirely too many cases of people doing something wildly unsafe and reckless because it seemed the easiest to them at the time and their tools didn't handle things for them. Use serialized objects to communicate between systems? Why not? We have Avro schemas, those will keep us safe as we deserialize random data from the network, right?
As much as I don't like being treated like a child by a bucket of bits, I also recognize that Clojurian minimalism requires me to think of literally everything. I have to know everything that's dangerous, how it's dangerous, and how to guard against it. That feels like even more load on my brain than being babysat - and I'm a security specialist!
Moreover, finding developer experienced in react is much harder and more expensive than those who do traditional HTML-CSS combo. Finding a freelancer to slice out PSD design into HTML-CSS is also much harder to go wrong. I wouldn't be comfortable outsourcing a react project to freelancer I barely know, but I'd do it for HTML-CSS.
I'm not against react or other SPA frameworks by any means. I think they're great technology that makes certain use cases convenient and can make a good user experience. That being said, there are also costs for those, and I just feel like there are so many websites out there that don't actually need to be implemented using SPA. Traditional server-side rendering would have saved them so much time, resources, and headache.
I personally would only rewrite a particular project into an SPA when there's a real need for it. For example, when the user base is large enough that a nice-to-have user experience becomes a big enough deal, if there are real needs for "reactiveness", or if mobile apps counterparts that would also require REST API is needed.
On paper, Pheonix should be the default choice for large and small web/mobile MVC applications. I think the question of if that becomes the case is directly tied to adoption of Elixir.
I'm stoked about the potential of live view and I'm curating a list of demos of things built with it: https://tefter.io/zorbash/lists/phoenix-liveview-examples
It took me a couple of hours to build my first demo with it, have a look: https://youtu.be/tTPH4DyUaUk and I didn't have to write any JavaScript for it.
This post rings true.
I gave nextjs a try recently to build a simple dashboard that could connect to our oauth provider. Forget external libraries, even simple ways to do state management, user login, screens, HOCs to guard routes - all of this is poorly documented, managed, and there are 100s of github gists that aren't versioned, demonstrate old APIs that have been deprecated and aren't really usable unless someone who knows that they're doing goes in, and cobbles together an example.
The last sentence was written to mean that unless you go in and spend a LOT of time reverse engineering code from a myriad examples, it's almost impossible to get a working implementation.
Rails (v4 was my last experience) was hard for me and I think my reasoning is as follow:
- I like to dig deep into the framework I work with but Rails have so much meta programming (a.k.a magic) that I struggle real hard figuring out stuff. You often have to go into runtime, hit method and see where it lead you to and after a while, I realise that I'm not going to see the bottom.
- If you are someone who like to dig deep, the documentation wasn't helpful for me at all.
- ActiveRecord for a while discourage using foreign key. When I move away from Rails, I tried SQLAlchemy and love that its unopinionated. Then I move to node and agree its ORM are less powerful but I learnt to love SQL. ActiveRecord for me shouldn't be any more than just convenience ORM and shouldn't replace SQL, that goes against Rails' ActiveRecord philosophy which claim these constraints should be at the model side rather than DB side. https://guides.rubyonrails.org/active_record_migrations.html...
- Lastly, I firmly believe MVC is a leaky abstraction. Any variations of MVC is just shifting the complexity around, not reducing it. I worked on Rails, worked on iOS (which uses M-V-VC). The pattern I see is that almost every year, someone will get bitten by vanilla MVC, tried some variants unsuccessfully and conjure a new variant; the cycle goes on. MVC is a 20 year old pattern, it have amazing insight into how we should build application, but its implementation always fall short after so many years.
Ultimately, I don't think Rails was optimised for someone like me. I think there's just fundamental differences in philosophy between me and Rails.
More like 40; it's from late 70s Smalltalk.
Then what is the abstraction that you think it should replace it?
Is it that we need to offer offline clients to meet user expectations?
Better raw performance on the front end?
Cheaper server costs or easier to deploy serverlessly?
For the progressive enhancement of your resume?
And "there's no reason you can't, if you wanted" is a far cry from "sure, the work is already done."
For example, something as simple as having a server-side rendered forum built with your favorite back-end language and now you want to build a client for it (web, iOS, Android).
That basically means massive duplication as you create a json interface boundary.
Yeah, you were already passing a { user, topic, posts } object to the template, so you can just serialize it your json api, right? But you can't because when you wrote that code, you knew the data never left the process. You didn't need to scrub the user.password_digest. Adding an api on top of an existing system is a lot of work no matter how much you hand wave about "well architected software."
But forget over the air network boundary. How about just wanting to implement the view layer of your Rails app with Go one day? How exactly would a "well architected" Rails app help you out?
The truth is that one reason that SSRs are simpler is because they are monoliths which spares you from certain classes of concerns. That's the trade-off you have to pay for if you want to cleave the monolith one day.
Moreover, no one stops you from separating concerns on the server side.
I’m not sure if the 20 extra client/server roundtrips increase raw performance though.
I personally think React’s component model is much nicer than any templating system I’ve used as it supports composition as a first-class feature.
And if done well, yes you get better performance on the frontend. (If done poorly, you don’t.)
This is my feeling too. Composition and JSX beat logic in templates.
Though I've seen some pretty hairy React, I still prefer it to badly implemented template files.
I've also heard that graph dbs are better for social data than relational dbs, though I don't know the details. So I guess another use case is you are Facebook.
Rails/ruby perf is getting better with some new work in ruby with JIT and memory. It's got its work cut out to match up with Go, Elixir, or Node, but compared to the rest of the options, it also has a huge head start on some other basic things like community and support.
In my case, I've had to deal with a form-heavy application, where React adds more boilerplate to form handling than just using the DOM.
I've really never bought the performance thing about a javascript-heavy SPA. I'd much rather see progressively-loaded html content than watch a loading indicator. I'd really rather have slightly longer page loads on average than deal with the long wait, and then hurry up and wait of the typical Single-Page App.
For instance, let's take writing a simple RESTful API. With Rust and Rocket, I need to build up the file structure, start writing controllers to fetch the different resources using diesel, figure out connection pools and how they link with Rocket fairings, then find I need rocket_contrib in order to automatically serialize to Json, then write out all the same routes (/ GET/POST, /:id GET/DELETE/UPDATE, etc.). Meanwhile in Rails I type `rails generate scaffold article title:string content:string`. Boom. Done.
Several times I've found myself thinking about ways of making my development experience better in Rust. Maybe I could write some macros that fix my problems. But then I'd just be reinventing Rails' metaprogramming. Ah well. I guess sometimes we need to reinvent the wheel.
For example, let's compare 5 legacy Rails apps (each at a different version since this is the real world) to 5 bespoke Express/Sinatra apps.
One upside of the Express apps is that all of their glue code is right there in plain sight. You can go into each code base with a blank slate and read the code to understand what it's doing with zero dependent knowledge.
Having worked on Rails apps as part of my 7 years as a contractor, you don't get that benefit in a super framework. You need so much knowledge about Rails to follow the trail through an application. And it gets hard to keep things straight once you're jumping around old versions. Even stuff like "wait, where did this variable/method come from again?" and being able to quickly ID it as something Rails itself provides vs something else (application code or gem).
Or how about figuring out how authentication works in each of your 5 Rails apps that use Devise? If you're a veteran, you know to look for some magic options in config.rb/devise.rb and you know what they translate into. Otherwise it feels like credentializing in a black box.
I think that things like React and Express are toppling the old guard idea of Ember and Rails that large applications somehow save you from work. When Rails was hitting the front page of HN every day 9 years ago, the meme of the day was how much you could do with so little code. DHH showed you how to make a blog with almost nothing but `$ rails generate`. Want a user-avatar system that uploads to S3? Just drop a few lines here and there: https://github.com/carrierwaveuploader/carrierwave#getting-s... -- this was the spice of Rails.
The benefits are almost undeniable upfront, and the down sides of the trade-offs they make usually take a long time to fruit, so they're hard to quantify. But they're there.
But I can't tell you how many times I've deep dived on a client's old Rails app with pencil and paper into the wee hours of the morning wishing it was indeed just a "microframework that half-implemented Rails" if that would mean I could follow actual code from A to B.
Don't get me wrong, there are always trade-offs and there is never a best. This isn't to lambast all Rails apps across the globe. But I see the "you're going to either use Rails or reinvent Rails" meme a lot to discourage smaller frameworks more often than I see someone point out the other side of that trade-off.
Now, which
Also, Spring Boot saved that whole organization from irrelevance. It took a huge amount of effort to just get hello world on the screen prior to Spring Boot.
My team is still building server-templated web apps with Django, RoR, Laravel. It's just that most software we make is some sort of CRUD application and React/Redux feels like overengineering, and still a mess when it comes to SEO. Clients are happy and ultimately don't care. Should I be worried?
Having tasted the joys of static type checks combined with a unified front/back data model, IMHO, that’s unthinkable.
Would you mind elaborating on the specific benefits?
This takes 99% of the fear out of refactoring and expanding APIs which leads to incredible agility in adding features to an existing code base.
Your team is likely using an overly restrictive tsconfig.json. No-implicit-any, for example.
Make it less restrictive, and you then have typing and no penalty for punting on it until later.
If using an IDE, the effort into defining types is immediately rewarded with autocomplete for API/backend AND client code, and we even export the types for use by a Monaco editor inside an internal app.
If I never have to explain <!-- ko if: !condition --> vs <!-- ko ifnot: condition --> again, I'll be a happy man.
No more grepping an entire codebase to see all the places that something is referenced and praying that you updated all of them. (And praying that you updated them correctly!)
How do you get that? Are you using GWT?
If you don't have page-specific (or any, if you can) code on the client side, this stops being a problem in the first place.
It's funny how SPA fans here claim both good separation of concerns via web services and code/type sharing as features while in practice those things are mutually exclusive.
Sure and that's a valid use case for server rendering. Though even in that situation having a typed mechanism for going from a model and view to HTML wins out over untyped templates that operate primarily on string replacement. You have the same problem server side when "first_name" in your model is renamed to "display_name".
Unless you have tests that lead to rendering every possible if/else branch in your rendering logic, you're not going to realize that you forgot to update your view template until that situation happens in production. The more complicated your views, the more likely you'll run into this situation.
> It's funny how SPA fans here claim both good separation of concerns via web services and code/type sharing as features while in practice those things are mutually exclusive.
I'm not sold on SPA either but for any application that involves an active client that makes it's own requests and maintains state, you end up needing some form of documentation for those interactions. It's not a panacea but well defined interfaces shared between the server and client solve a big part of that.
I'm using Phoenix and Elixir these days instead of Rails. But I've also been circling back to C# after 9 years of not using it for anything. C# has become to so incredibly open that you can write C# code and build static binaries for Linux, Mac and Windows, with single commands. Definitely check it out if you want something like that under your toolbelt.
The fact is, the javascript ecosystem is a house of cards. Most definitely the worst ecosystem I've ever used to write software. I sometimes wish a competitor to NPM launched with better organization and rules. NPM is insane, in all the worst ways. Google the left-pad incident. We need JS so we're stuck with NPM I guess.
Maybe with Phoenix LiveView we can get away with _less_ JS - maybe...
As for Roda, idk why but it just doesn't click with me.
Until now I use it every day and I found it's really great and better than my previous impression:
1. Compared to JS there's always a specific way of doing things - how to validate, how to dispatch async Job, how to send emails and real-time notification etc.
2. Compared to Spring there's only a recommended default way you can easily start with. You don't struggle with SpringWeb vs WebFlux, different JMS implementations, Hibernate or query builders, etc.
This is so important. When doing something on rails you always get instructions on the exact things you have to do where as JS always seems to either give you 500 different versions of the instructions or just expects you to work out how to set it up based on everything else in your project.
I don't understand why these types of features are so sorely lacking on other frameworks. I was looking for a simple user management dashboard for MVC and maybe my google fu was lacking but I just could not find anything easier to implement than spending a day writing my own stupid dashboard...
A lot of people here complains about Rails performance, and that is one of the reasons why I use the Grails - Java framework. It is not as polished as Rails, and has a few sharp edges, and it has a much smaller community which is still super-friendly and awesome. Grails however can still take the advantage of the enormous Java ecosystem. You have a library for about everything. And many of them is of really high quality too.
I have for the last five years built three successful startups with Grails, where the last one now employs 100 people. Grails has been really helpful here, as it has made it possible to move fast and add,fix,improve,break changes quickly. For my last startup Rails would most likely have struggled with the amount of data we are dealing with, while Java is hardly sweating. It is not something Grails specific, but still a part of the Grails application, that is why I mentioned Java.
My last startup, which now employs over 100 people didn't use React nor Angular either in the beginning, just vanilla Javascript. More speed, less complexity, less errors and so on. We use React today, but that is because new employees really really wants to work with. And developer happiness is really important.
And if you really needed to get "out of Grails", there has never been an issue using the Spring MVC api or Spring Boot with Grails 3+
This kind of engineering directly leads to endless wasted hours troubleshooting errors, routine build fails and apps that think nothing of pulling in hundreds of dependencies that in turn have their own dependencies that can fail at any time.
This is plainly wasting millions of man hours of end users time if its not a SAAS app. Compared to that Go is an ode to simplicity, PHP just works, Python is relatively painless and even Java causes little stress. Its node and ruby that seem to be designed by people who revel in complexity and have zero concern for deployment and end users.
Then eventually the requirement for more application-like experiences led me to adopting client-side frameworks because server-side just wasn't able to do those things very well. I like the idea of a json-based api talking to a client application, but the client-side libraries have bought back all the things I hated about desktop UI programming.
I think html is great and should be left on its own, not combined with the programming language. That is the reason I don't like React. I can't read all of that jsx/pseudo-javascript together. It looks like a mess. Vue is better, but it is just a big hack of stuffing things into html attributes. Both of them also require a compile step if you want to use them to their full potential. So now all the things I hate are back, and I don't like web programming anymore.
As much as I've grown to despise the Ruby community for relying too heavily on metaprogramming and inheritance, leading to abstraction hell, I think Rails is still a great framework for serving web pages. Just because it's not the shiny new thing doesn't mean it can't do most of the things we want from it(not every company is FAANG scale), and there is still an abundance of Rails jobs in 2019.
My current middle-ground stack is Golang API (I use go-chi) + (LitElement front-end (web components) + Redux). I'm kinda happy, though my gripe is with Go sometimes, not the stack.
To the far right where people are complaining on: React + GraphQL, etc. Well, I think you went into the deep end, so rightfully you think about veering back left again. But hey, there's a middle ground that is more "standard's based".
Devise was the ultimate example of this. `rails generate devise:install`. Instant authentication system with almost zero changes to your code base.
Yet now something as central and important as authentication is implemented outside of your application in some highly abstracted software. To do something as simple as figure out the name of the cookie it sets, you have to either dive into its internals or look at the actual cookie it sets instead of just reading code that should've existed in your code base.
Rails was the first "language" I learned so I was its best case subject. It was able to indoctrinate me in the beauty of metaprogramming and things like that. Yet that still wasn't enough to keep the light from shining through the veneer when working on a real world projects where you just want to know how something works by reading application or glue code, not daisy chaining through a bunch of library code or hoping you cache-hit the library's FAQ so you don't have to deep dive.
There seems to be a lot of "why is there no Rails in {JS,Go,Rust,Clojure,...}" lately and it's no surprise to me why there isn't. The same reason Ember and Meteor never took off to the degree that React did.
There was some sort of "glue code just isn't that bad" renaissance.
> Rails was the first "language" I learned so I was its best case subject. It was able to indoctrinate me in the beauty of metaprogramming and things like that. Yet that still wasn't enough to keep the light from shining through the veneer when working on a real world projects where you just want to know how something works by reading application or glue code
I think the hidden magic is the worst part, but after a while I got pretty good at simply diving into various gems to see where the magic's happening (or failing to happen) and I don't mind that aspect now.pry is an awesome tool. Put a `binding.pry` breakpoint in your code, do a `show-source Foo.borked_method` and explore from there.
Also, popular Rails-related gems tend to have good tests. I learned that those tests often demonstrate things that the docs don't.
Sure it's kinda complex but their interface makes every form of extension rather easy.
Yuck.
I feel like the Rails community owes a lot to Ryan Bates for pushing out high quality content and keeping up to date with Rails for as long as he did.
If anyone ever has suggestions on Ruby / Rails topics to cover, let me know!
But I do agree that it seems the JS ecosystem is missing a real Rails equivalent. Specifically an ORM that is as robust as ActiveRecord. I've often thought about building this myself, and then I remember I have a family and full time job.
The lead developer is a ex-Rails developer with a very keen sense of what made Rails successful. One of the reasons that it's still pre-1.0 is that it won't ship until the plugin architecture is good, which speaks to the point of the article.
You don't need advanced syntax in the server code to write Rails applications, so Go may be a good fit for a Rails replacement.
Actually I have gone back to server-template development using Django for selected projects, after many years working with React, which I still love.
Server side templated development with Django can be extremely fast in terms of development time, very direct and effective.
There no need to use React for all the things.
Sometimes React is the right tool, sometimes server side templated is the right tool.
I can build a traditional server side rendered app or I can use the front end scaffolding to build an API driven SPA based on vue or react.
If you want an SPA type Rails way of doing things, you can use Turbolinks. This talk at RailsConf 2016 is really an eye opener.
Then, I decided to delete the folder.
I remember watching Windows building the list of about 1GB+ of files to delete. Only to have it try but couldn't complete the deletion process because some file names were too long because of the recursive nature of folders and dependencies in `node_module`.
Good times!
I'm not sure how a combined framework for server and client side would work.
Rails is still the number 1 backend framework, and the RoR ecosystem is so powerful that the https://hyperstack.org gem lets you code in Ruby on the client, and fully access your AR models directly in your client code (again all written in Ruby.)
You get all the maturity of rails, including be able to use Rspec to test your server and client code in an integrated fashion.
Here is a blog post that shows how simply adding a 2 line AR model declaration adds data persistence, and push synchronization to a "client-only" app: https://medium.com/@mitch_23203/the-exact-same-app-in-hypers...
If that is not "modern" I don't know what is.
Meanwhile the rest of the world is writing tons of boiler plate, creating reducers, transformers, co-axial independent state repeaters, I don't know what all, but the bottom line is you have to write a ton of code to get anything done.
Rails applications benefit from batteries included boilerplate because Rails "owns" the whole stack.
"Modern" (contemporary?) JS applications benefit from separation of concerns, and flexibility because each layer is interchangeable.
So how do we make this better? We can't reasonably split Rails up to match the benefits of JS. The obvious (naive?) solution is to provide a protocol that JS layers can follow. Specific packages/layers can decide to provide the protocol which makes them interoperable. The developer may then pick and choose, knowing that if they choose packages that comply with the protocol, they can use the "batteries included" features.
It would be fairly trivial to identify the major features that most apps reimplement. Getting it all to play well together would not be as easy.
As the OP described, I think Meteor was a great platform, but had some fatal flaws. If "Meteor-the-company" was "Meteor-the-protocol" I think we would have been in a much better position.
Please stop. At this point you're spamming. It's great to be excited about a project, but you're gone beyond that now.
Check out: https://twitter.com/joerichsen/status/1109122286139965441?s=...
I have been particularly interested with Phoenix as of late as it fixes all the gripes I have with Rails and Liveview is an amazing pattern that I think would simplify a lot of things.
We started with a Rails project two years ago. It's a bit slow, but dear god we get so much done with it. That being said, having Typescript on the frontend makes it so utterly clear how much better Rails would be with static typing.
Or even a pry-remote equivalent?
It already has impressive code generators for GraphQL.
Amplify has a pluggable interface for different cloud providers, but I guess until Amplify reaches critical market share, nobody will implement the Azure and Google Cloud parts...
Maybe you go multi-cloud and your AWS only competitors crush you, because you spend money and time on the wrong thing and their one-provider-setup just integrated so well and saved so much time and money.
Maybe AWS goes bad quick and you can jump ship with your multi-cloud setup and save your butt while your competitors go down with it.
I just don't know :)
Sysgears has some other projects that is moving towards the ability to import functional modules from npm
I work primarily on the backend, so this could be incorrect. But I'm curious if anyone else has been aware of this trend, or if I'm identifying something that isn't really there.
Feature/Improvements introduced in Rails are constantly being picked up by other frameworks but for some reason, people are ignorant about the progress made by Rails in the last couple of years.
I use Rails every day at work and trust me when I say this, It is so easy to get back to the code written last week or even last month(Of course Ruby plays a big role in that). It is a big advantage when you do not have to break your head every time you wanna review your code which is written some time back.
When I then looked into Rails again (years later) everything felt so natural and right suddenly. However beginner documentation also got a lot better so this was surely part of it.
Need authentication? Just turn the feature on in Firebase and use it. Need storage? Need analytics? Just do the same. The future is bright and we are heading in the right direction. With this, we can get started on our apps with zero configuration and just focus on features.
And if you pick a neat tech provider and it goes belly up (like Parse!) you’re in some real pain.
That said, with pry, it's pretty easy to dig down into the "magic" and see wtf's going wrong when something is borked.
Despite that minor grumbling, I'd say that Rails is still darn good! It's very mature framework (or perhaps more accurately, collection of frameworks) at this point. You can get stuff done quickly.
Most things really don't need to be SPA, and many (most?) don't need to serve up more than a few hundred or a few thousand responses per core per second.
- Compile Graphql schema into Typescript typings + Fragments for "Active Record"
- React Hooks as controllers action.
- React Suspense for HTML rendering.
- Apollo for graphql caching
- ExpressJS for middlewares.
- @reach/router for routing.
- @loadable/component for code splitting.
- Serverless for API.
I missed Rails, too. But i found that the "modern stack" is not bad at all. It just needs more time to investigate to find out the best way to reuse features.
I hope the DX will get better soon. But this stack beats rails on scalability, universality, user experience, and many more. It's a trade-off that i found worth the effort.
Seriously, gang: Rails is productive, fun and lets you focus on making your customers happy instead of optimal package composition.
But this is a trade-off i take into account.
I even have a production system running on Rails, with frontend React.
This stack's benefits to me:
- Universality (one Typescript to rule all backend and frontend)
- Separation of concern (no more MVC, only components)
- Scalability (each part could scale independently)
- Modularity (the business logic now could have its own service as a graphql API)
- User interactivity in less code (this is why SSR with React)
My new application on this "modern stack" is nearly to be released. If you want to know more, ping me on twitter @revskill.
Put differently: how much more time and energy would you have had to work on your MVP if you had just used Rails?
Want new feature ?
- Add a graphql API (if not exists) and compile to Typescript typings.
- Develop and deploy a React Component for that feature.
- Install and add to the application.
Further, being stuck in a box also means that the community can rely on that very box and add more extensions with the architecture of the box in mind. A box gives assumptions to build on top of. Sure if you really really need a triangle it’s painful, but then you should ask, do I really need a triangle?
I think the real insight of DHH is that most web apps are not as “unique” as developers would like to believe and that the harmony that comes with conventions, the speed that comes with a unified end to end integrated system, and the focus developers gain for actual impactful choices when many unimportant choices are made for them is an amazing improvement.
He said recently, that insight is as controversial today as when he launched rails, and he is surprised more rails competitors haven’t emerged.
I think the first end to end GraphQL > Single Page App framework that has a similar level of integration to rails will dominate.
I don't think that ever existed "THE standard way" to build web applications. At the same time Rails was trend, for a lot of people the "standard way" to build web systems was write it from scratch in PHP.
I too find react etc too complicated for a simple crud kind of app. Rails was much faster to achieve the same.
I wish people didn't start their posts with such proclamations. Why can't one just go ahead and criticize something without first giving it a compulsory doze of praise.
Why? What is wrong with that exactly?
Has the Internet fundamentally changed over the past seven years? I’d argue it hasn’t fundamentally changed in the past 20 years.
A single-page app isn’t a panacea, and in most cases is a bad choice for a business.
Thereby validating the author's premise that "the majority of the problem is just a result of fragmentation in the modern ecosystem."
And I can't wait for activerecord to be replaced by something like objectmapper.. It makes a lot more sense.
So uh... I run a Rails / graphql backend and React / Apollo frontend. It's not perfect, but I still think it's easier than running a complex node backend by an order of magnitude.
These days, frontend has advanced so much that either you are a minority who is truly full stack and can do both backend and frontend work in good competence otherwise, frontend has become a separate profession altogether and for good reason -- it not only requires artistic capabilities, but it requires good amount of coding now with plethora of frameworks/modules.
Rails is a great framework no doubt but advent of React/Angular along with rise of microservice-oriented architecture has limited the footprint of rails in job market.
The biggest dealbreaker was that (like most Rails apps) we had a ton of gems, some of which had native extensions. JRuby doesn't support C native extensions.
In the end, it was way easier (and a much less risky change) to spin up our own Java REST APIs in front of those JARs, and let our MRI Rails app integrate with them by talking to those REST endpoints.
Just for fun, I also tried using dRuby so an MRI Rails app and a small JRuby (non-Rails) process could communicate idiomatically. It was cool, but I'm pretty sure dRuby was eventually deprecated.
Does this story answer your question about performance? Not really, but if I wanted to dive deeper (which I do at some point!) I think TruffleRuby is a real option.
With clear outstanding options for authentication, image processing, and all the other bits that are commonly needed?
I would highly recommend JHipster to bootstrap a new Spring Boot app. It does monoliths or microservices and gives you a great scaffold to build on top of.
There is a JHipster Kotlin blueprint that generates the backend code with Kotlin instead of Java. Can't wait to use it.
I hate it but I'm no Java expert.
Virtually no-one's updated from Grails version 2 to version 3, or released any plugins for version 3, so it's hard to believe anyone's interested in a 4.0 release.
> "Now, I know Rails isn’t universally beloved by developers, and I’m not suggesting that we give up React and es7 and go back to writing server-templated web-apps like it’s 2012 again."
Why not, exactly? It worked well then and it works well now. Not everything needs to be some 10MiB javascript bundle delivered to a late-model version of Chrome served from a static bucket.
The other thing that's missing is db migrations - typeorm has decent migrations, so that can be leveraged.
It's not comparable to Rails in that we can't have plugins to install new things that work with the entire stack, but whatever we have initially is really good and I feel makes me very productive
Right now you have FRAMEWORKS being used in production at big companies, so if you use React, Angular, etc. you know that you're in good company. I think it would be super interesting having a large company roll out a full stack JS framework that they themselves use.
Just because Google wrote Angular, doesn’t mean it’s good.
Our project wasn't badly written, it was just that slow. Is it better today?
I somehow ended up working with PHP-based back-ends but for smaller projects and I sometimes miss Rails, because Docker for Mac...
For reference, the Rails app that I am working on, almost literally right now, is responding to HTTP API requests, performing authentication and resource authorization, creating a background job (or 2 or 3), and posting an event to kafka, in 2-3 ms. This is on my work-issued dev laptop from 2016.
If I start hitting the SSR portions of this same app, I'm getting response times in the 70-80ms range pretty consistently across the 6 or so pages that I just hit to get a quick baseline. No front-end frameworks here. Just turbolinks, ERb, HTML, CSS, and sprinkles of ES6 (served via webpack(er)).
It could be a query that isn't optimised with an index in the db, it could be best practice code that doesn't work well in the context of your app, any number of things.
At my last job we had a page that looked to be very well written, but it was taking 30+ seconds to render the page. Turns out to be a method we were calling 10x too many, because someone had benchmarked it in isolation and it didn't have any performance impact. However in conjunction with some of the data that occasionally passed through that method, those 10x calls ended up being a couple of seconds each.
That's an extreme example but there's little things you can do everywhere on a rails app if you know what you're looking for, and I would expect this to be the case in any web framework.
Repeat after me: Rails Is A Modern Web Stack. Seriously. You can do everything you might imagine needing to do for a modern web app:
Need an easy way to create server-side rendered (SSR) pages that still behave in a performant, snappy manner like all the cool kids? ERB + Turbolinks 5 is a powerful combo.
Need to ratchet it up a bit with dynamic interactivity? Slap some Stimulus on that SSR puppy!
Still not "modern" enough for you? Use React! Or Vue! Keep Rails operating just as a JSON-flavored REST API.
Need to push commands from the server to multiple clients at once? ActionCable to the rescue.
Need to offload long-running tasks to background jobs? ActiveJob + Sidekiq is the bee's knees.
At any rate, plenty of us are developing "modern" web apps and sites using Rails, Webpack, and other cool frontend tools, and it's going quite well. I don't feel in the least like I'm missing out on something amazing or obvious by sticking with tried-and-true, stable tools that have been my bread and butter for 11 years and counting. DHH's philosophy of web programming may not appeal to everyone, but for many of us, he continues to a voice of reason in an insane world.
Built with Meteor, React, and GraphQL.
I always preferred Flask, because it gave you a minimal framework, allowing you to cherry pick modules as needed. Sinatra looks similar if your preference is Ruby.
I cannot say that a Node stack is better though. Both Rails and Node are fairly awful, but for entirely different reasons.
Usually all it takes is to lookup the source (which is well commented/documented) to see where the magic is coming from, the code is fairly easy to understand. If it works well use it, or take what you like/want and write your own methods, classes etc.
Any modern language is pretty magic. Think about what is going on with Javascript JIT, or even Ruby. Its pretty crazy magic.
And its not actually magic, its just abstracting out details.