Choosing the Right Rust Web Framework: An Overview
shuttle.rs
shuttle.rs
Take handling datetimes for example. Do I use time or chrono? The initial developer/maintainer of chrono left[1] and for the longest time the crate was unmaintained while a CVE remained open[2] until a new maintainer finally came along and addressed it (I think?). All right, so, time it is then... but it uses its own custom format specifiers[3] that I had to get used to coming from the more familiar strftime used by other languages.
Or how about input/form validation. One of the most popular crates for that, validator, had its maintainer admit that they don't even use it themselves?[4] Of course I can already hear people yelling at me, "well, why don't you contribute then?!", and I certainly would love to if I could! But I have to finish what's in front of me first.
That being said, I still very much enjoy using Rust. Maybe less so for web-related projects. I just have to stay on an even keel despite the growing hype.
[1]: https://old.reddit.com/r/rust/comments/qamgyh/is_the_chrono_...
[2]: https://github.com/chronotope/chrono/issues/602
[3]: https://time-rs.github.io/book/api/format-description.html#v...
A "framework" is a thing which calls your code rather than the other way around. You're confusing framework and "full stack" framework.
Actix or Axum are web frameworks in the same sense Flask or Sinatra are web frameworks: they deal with the HTTP lifecycle, and call your code when certain conditions are met (usually around routing).
I really like the style shown in the examples in TFA. Is the style shown in the examples pretty typical in the ecosystem? Is there tooling that will achieve those results?
If it's your job to make those technology decisions, you better stay informed lest you paint the whole project into a corner, if not immediately, then a few years down the line.
That's interesting, in my experience doing consultancy in bunch of small to mid sized companies, failure seems to most of the time come from anything but technology and much more around people, groups, relationships between those people and groups and how work is organized on a weekly basis.
- https://crates.io/crates/axum
- https://crates.io/crates/actix-web
- https://crates.io/crates/warp
- https://crates.io/crates/rocket
- https://crates.io/crates/poem
these numbers pale in comparison to download stats of web frameworks in other languages (ie Flask, Django), but they have grown significantly in the last 3 years
my guess is that Axum is what AWS is using internally, else the grpc counterpart server called Tonic
Compared to other frameworks I've used (Rocket, or frameworks in other languages), I've found Axum to be challenging to get up-and-running with.
It's hard to figure things out from the docs. Basic features require 3rd-party packages. I have to guess my way out of compile errors because the error message & their types are unintelligible. And Axum transparently passing on the underlying Tower (and Tokio?) concepts piles on how much knowledge is required to use the framework.
To me, Rocket has always had the best ergonomics to get going and Actix with macros is a close second.
That's what I really like about the Elixir ecosystem; Phoenix is the automatic no-brainer choice. Just crack on with building your idea.
Yes cohesion is great! For C# we have ASP.NET dominance (and Java has Spring?).
At the end of the day our job is to deliver value.
I spent quite a bit of time trying to understand the distinction between these options and when you would choose one over the other, and I would have to disagree that it's a no-brainer choice. Perhaps if you've been in the .NET ecosystem for years and have followed the changes but definitely not if you're new to it.
- Razor pages, views and components use the same templating language.
- If you want MVC you can use Razor views and Components to render things from your Controller.
- If you want something simpler like a website, you can use Razor Pages and Components.
- Blazor is the new shinny thing. It still uses the same Razor templating language but targets for webassembly or Phoenix-style LiveView.
And for APIs, it's just the ordinary Controller -> Action -> JSON as every other framework.
If people just saw coding as that, none of this innovation would have happened.
Take Uber for example, it required no technological innovation (still great feat of engineering of scale).
Meanwhile ChatGPT did.
Both deliver value.
Also, there was a moment in Rust history where people near the core Rust community were striving for a std library variant and that didn't go well, politically. There were several options already in the ecosystem and it was a pet project that would challenge incumbents.
the REAL befit of elixir is also that the entire underlying ecosystem is one big toolbox for networked applications and the performance for most web tasks (IO bound stuff) is on par with rust.
I run a startup on elixir myself. unless it was an exceptionally small service (or serverless lambda), I couldn't see myself choosing rust over elixir. that said, I could see myself writing a nif in rust via rustler if i ever need the performance benefits.
Anyone reading this who wants to jump in the ring-- show me how to handle an event triggered by a row in a table accessed through a tab-navigation component, updating the table. As an encore, show me how to carry state from plug middleware to a liveview function. Each situation involves contortions and passing state between steps due to designs yet to be refactored.
nope, liveview didn't exist when I started this startup. its an ios app connected to an elixir api over graphql and channels.
> The learning curve is a major pain in the ass once you go beyond hello-world.
I made an app in in while back. there's def a bit of a learning curve but its not that crazy. I was able to build a few fairly complex modal workflows in about a day. conceptually, its juts a genserver with a set of frontend components into which you load state. which can send back and forth events. Nothing anyone not familiar with react/redux wouldn't understand.
> show me how to handle an event triggered by a row in a table accessed through a tab-navigation component, updating the table.
the live view way there if I understand you correctly would be to give each sub component an id that it can pass back to a stateful main component whihc it would then modify in place and autoupdate. in practice, if performance is an issue, you can embed a javscript widget and send only necessary information back and forth using phx-hook. elixir's ecosystem has been great about getting out of your way when its not the best tool for the job.
Typically a critical question at HN will get downvotes because it is not encouraging or constructive or whatever, but that's OK as I really want to know the answer here. I understand Rust is cool for system programming, but I don't feel Rust is good for _everything_
Assuming you have some cash to make web related products, are you going to use Rust web framework at all? I know I won't.
Prototyping is slower but maintenance is faster. It's a trade-off.
I have a bunch of products and every once and then something needs fixing. When it's one of my node.js or python projects it's usually a bath of blood and I'm never confident I changed the right things.
With Rust I get a type error until everything is plugged in correctly - the only mistakes I get are logical ones.
TypeScript kind of gives you a similar experience but it has more escape hatches. If you want to close all the exceptions and make everything type safe it will take you a similar amount of time as writing Rust code.
The end result is that when I see a TS codebase I can't trust it: I might have written some unknown / any and there is a massive gap in types. This negates any benefits I get from type safety.
In Rust this is not possible, as long as you're using safe dependencies (which you most likely are if you're writing a web service in Axum).
I would imagine it's one of those "I already know Rust really well and I want to write a web app." Phoenix (like Rails back in the day) is one of those frameworks that makes it worth learning a new language, but those are the only two I know. The rest of the frameworks I've seen compelling are mostly to allow somebody to stay in the language/ecosystem that they're most confident/familiar with.
But seriously, I don't know. It seems like it trades development speed for things that just aren't problems. I think the database would be where most performance issues would surface, not the api server. I'm curious how others will answer your question though because I'm not really sure.
The constraints it imposes pay dividends. Do you write code once and forget it? Or do you often change what your code is doing or how it is structured? Because those changes tend to bring out the most bugs. The type system will really help you with any refactorings. I've done some huge changes to the entire structure of my apps and once it compiles had zero issues. It just worked from first run.
Do you find performance problems in production? How much time is spent on those? If you're in Python/Ruby/Erlang land that can be a huge chunk of your time. A Rust solution is going to be memory and cpu efficient by default. Unless you are really in extreme performance land you are likely not going to need to bother with this at all.
How about problems with deployment or dependency management. The output of rust is an executable more or less self contained. The package management is superb.
Yes, it is faster to develop initially, but after N years and an established product that development speed gets outweighed by other requirements: how easy is it to refactor confidently? How much does it cost to run? How complicated is the deployment? Does it scale?
Not to mention many of the reasons why it's faster to write is because you're punting on handling important issues: can I pass this to that function? Is this a valid state for this variable? Is this data validated?
A language like Rust might bog you down at first because it'll require you to do all of that before you get off the ground. But I'd be willing to bet that, if you factor in the whole cost for N years, it'll eventually turn out cheaper. And if you have experience in it it might not even really slow you down.
Many would say "yeah but you have to survive N years", and maybe I've just been lucky but most of the products I've worked on have been profitable and successful. In all of them we reached the point where it just wasn't as fast to develop anymore, and now the application was very expensive to run, slow to change and filled with nagging bugs.
I have built several APIs with Rust + Axum + Sqlx. I get statically typed SQL queries, rock-solid performance, easy to deploy. Most of these APIs also interface with AWS stuff at some point, and the Rust SDK is just phenomenal to use.
But I also love Rust. I've been writing it for 6 years now, and I am more productive in Rust than any other language (for non-trivial projects). I can write up an API faster in Rust than in Django, because I don't have to spend time digging through configuration files or installing plugins and reading arcane documentation to do what I want. The above stack in Rust is incredibly simple.
I have a few dynamic queries, but for the most what I'm doing is relatively straightforward. I still prefer this over using an ORM, personally.
I found that both the parameterized SQL and ORM/QB have an important role to play due to the partial updates and occasionally query building exercise. None is ideal for every situation.
struct Bar {
id: Uuid,
column_1: i64,
column_2: i64,
column_3: String,
column_4: Uuid,
}
struct UpdateBar {
column_1: Option<i64>,
column_2: Option<i64>,
column_3: Option<String>,
column_4: Option<Uuid>,
}
UPDATE some_table SET
column_1 = COALESCE($1, column_1),
column_2 = COALESCE($2, column_2),
column_3 = COALESCE($3, column_3),
column_4 = COALESCE($4, column_4),
WHERE id = some_id;
Or, you just never do partial updates :)Heck people use some incantations of Java for High Frequency Trading even.
Besides, web application bottleneck is usually the database.
Goes to show how benchmark minigames are broken and also that most languages are good enough.
Other languages have some of those features, but not necessarily all.
3D printers are an area where I've been kind of expecting Rust to eventually take hold. Printers require fairly performant systems level firmware but the trend is toward users interacting with them pretty much entirely via webui.
Right now, Klipper is one of the more popular 3DP firmwares. It's a mishmash of Python and C at the firmware layer with Moonraker (Python) sitting at the API layer and then some soft of JS-based UI like Mainsail or Fluidd sitting on top.
I can see very real appeal to squashing the firmware and API layers down into a more coherent stack. Having a batteries included web framework would be helpful there.
And the answer is you wouldn't use it if there's a library or existing codebase in another language that is much better than the Rust equivalent, and the program is short enough that it's simpler to directly use that language rather than writing a binding or RPC interface.
Or if you need the software to be written by someone who doesn't know Rust and doesn't want to learn (but in that case, they might not be able to write a correct program in any language, so this strategy is probably best reserved when a program that only works properly sometimes is acceptable).
As good as Rust is, there is no such thing as "best" language.
I can't think of any other language with the combination of safety guarantees, high level language and a community producing very cool crates.
Rust dethroned Haskell for me, and I'm excited my favourite language is actually an approachable one for once.
I think everybody can learn Rust (unlike Haskell, I gave up on trying to teach people), you literally just follow the borrow checker until it works.
You don't need it. But if you prefer using it, it's nice to have a web development framework.
2. Code re-use between client and server. I have some application logic that can run on the server and on the client via WASM compilation
To put a web interface on a rust program. Suppose you have a program that does something very much non web related but well suited for rust, like embedded, or heavy CPU calculations, high speed control, etc. And suppose you want to add a UI or API or RPC or Prometheus metrics or monitoring or etc to a program, HTTP is often a convenient way to do it.
This is made exceedingly clear if you ask for specific examples of when Rust shouldn't be your first choice or when Rust is second-fiddle to more optimal solutions.
Once you have a few years experience under your belt, it's natural to want to use the language in other domains like large web applications, even though it's only a reasonable choice because you already spent the effort to learn the language.
That seems like a highly unrealistic claim to me.
they already killed scala, let's see how much time they need to kill rust
Or you’re working at one of the biggest project and need all the performance. Not sure it has ROI vs Java even then. Anyone with experience from Rust vs something else firsthand?