
Choosing a Rust web framework - LukeMathWalker
https://www.lpalmieri.com/posts/2020-07-04-choosing-a-rust-web-framework-2020-edition/
======
JackC
What's the security posture of actix-web these days? The impression I got from
the temporary deletion of the repo and maintainer switch about six months
ago[1] was that actix-web was sort of a research platform rather than a
production-ready server. It prioritized performance and ease of development in
order to try (successful!) ideas the author had for writing really fast
servers, and therefore made uses of unsafe code that many Rust developers
thought unsuitable for production.

I don't mean to start drama -- I just feel like if the project is still
prioritizing speed and experimentation over safety, that's worth including in
comparisons like this, and if it's not anymore (or if I misunderstood the
story in the first place), that would be good to know too.

[1] [https://steveklabnik.com/writing/a-sad-day-for-
rust](https://steveklabnik.com/writing/a-sad-day-for-rust)

~~~
steveklabnik
I think you misunderstood the story in the first place; it was always intended
to be production ready. The new team has, in my understanding, fixed the
unsafe issues, and development continues.

~~~
twic
It's a bit more subtle than that, in that it depends on what you consider
production-ready. It was originally intended to reach a level of robustness
and soundness that the author considered production-ready, but which I
personally didn't.

~~~
steveklabnik
Yeah. You could also argue that it was production ready because it was (and
is) being used, in production, by a lot of folks.

------
minimaxir
It's worth noting that actix-web has _much_ higher performance benchmarks than
other other frameworks mentioned, including the other async/await ones:
[https://www.techempower.com/benchmarks/](https://www.techempower.com/benchmarks/)

Looking at the benchmark code, it doesn't appear to be doing too many
shenanigans to hit those benchmarks:
[https://github.com/TechEmpower/FrameworkBenchmarks/tree/mast...](https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Rust/actix)

------
LukeMathWalker
Author here! This article started as a short section in Chapter 3 of Zero To
Production ([https://www.lpalmieri.com/posts/2020-05-24-zero-to-
productio...](https://www.lpalmieri.com/posts/2020-05-24-zero-to-
production-0-foreword/)) to give some background on the decision making
process I went through when picking the web framework we will be using to
develop our email newsletter project throughout the book.

It eventually grew to be so long that it made little sense as part of Chapter
3 itself - I thus decided to publish it as its own article and link it in the
introduction to Chapter 3 (hopefully to be released next week!).

------
WhatIsDukkha
This is a reasonable overview with a few caveats -

Warp seems to have one of the better api experiences but has significant
performance issues.

In the async world I think

[https://github.com/stjepang/smol](https://github.com/stjepang/smol)

is going to have a pretty big positive impact on the useability of the whole
system so I wouldn't rush to go all in on either async-std or tokio just yet.
Last I read it was still having some fairness issues that were next to fix
though.

There is also

[https://github.com/withoutboats/ringbahn](https://github.com/withoutboats/ringbahn)

Which is very disruptive in that io-uring doesn't have a natural async
interface?

~~~
wwright
IIRC, io-uring makes it very complex to expose a safe zero-overhead async
interface, because the kernel expects any buffers that you pass it to live
until the operation completes (ie, you can’t allocate your own buffer, give it
to the kernel, then decide you are uninterested and throw away your buffer).
In Rust, this would mean that any buffer basically needs to be 'static.

It should be possible to create a an API that uses an intermediate, managed
pool of buffers to pass to the kernel, but this would imply extra copies.

~~~
zozbot234
AIUI, withoutboats has described this issue in depth in
[https://without.boats/blog/io-uring/](https://without.boats/blog/io-uring/)
and follow-on blog posts, which also go into the design of ringbahn itself.

------
continuations
> As of July 2020, I’d suggest picking actix-web if you are writing a
> production API in Rust.

What about server rendered websites that aren't API? Which framework would you
recommend in this case?

~~~
Tyr42
I'm enjoying using Rocket so far. I really like the FromRequest way of
describing middleware and request guards. The docs are also very good.

I'm on the 0.4 branch, which isn't the 0.5 async branch, so I'm blocking on db
calls and such, but I'm targeting very low qps so I don't care.

I got the diesel database integration working with little fuss, and can guard
requests

    
    
        #[get("/me")]
        fn get(user: &User) {
            // Logged in view
        }
    
        #[get("/me")]
        fn get() {
            // Logged out view
        }

------
dap
> It took some time for the whole Rust ecosystem to catch up and adopt it, but
> it’s fair to say that crates dealing with IO-bound workloads are now
> generally expected to be async-first (e.g. reqwest).

Is this actually true? I've heard mixed things about this, including that Rust
itself has no particular position on the preferred concurrency model. Even the
async book[1] says:

> It's important to remember that traditional threaded applications can be
> quite effective, and that Rust's small memory footprint and predictability
> mean that you can get far without ever using async. The increased complexity
> of the asynchronous programming model isn't always worth it, and it's
> important to consider whether your application would be better served by
> using a simpler threaded model.

[1] [https://rust-lang.github.io/async-
book/01_getting_started/02...](https://rust-lang.github.io/async-
book/01_getting_started/02_why_async.html)

~~~
steveklabnik
The language does not prefer anything, one way or the other.

The community is overall very excited about async right now, and so the
community may expect things to be async-first, even if the language itself
does not have a preference.

------
rmdashrfstar
Alternatively, if you’re looking to create a web application but only expose
it through an HTTP API, you can simply choose an HTTP router like Routerify
[1] to route HTTP requests to a stateful handler and any number of
middlewares. I’m coming from Go and learning backend web dev in Rust, and this
crate has been a wonderful replacement for the Go library “Chi” [2].

This comes in handy when your frontend is a SPA (e.g. Vue, React) and it’s
just updating state via API calls

[1]
[https://github.com/routerify/routerify](https://github.com/routerify/routerify)
[2] [https://github.com/go-chi/chi](https://github.com/go-chi/chi)

------
xwdv
What’s a good PostgreSQL interface in Rust? Not looking for ORMs.

~~~
Spartan-S63
Diesel is going to be your most ORM-like option, which isn't what you're
looking for. `tokio-postgres` is great for async connections.

SQLx is also a really good option, too, and has some ORM-like features (such
as transforming SQL rows into a Rust struct via macros) while still allowing
SQL to be a first-class citizen. SQLx is also async, so that would probably be
the best one to look at first.

------
dgb23
Rocket seems to be something in between a full-blown web framework (Django,
Rails, Laravel) and a web server library, which is confusing.

~~~
stu2b50
Is it? It seems like exactly what you'd expect from version 0.4.5 of something
that aims to be a full-blown web framework.

Rome wasn't built in a day.

~~~
dgb23
Right, I didn’t look at it from this perspective. That was just my impression
of using it.

------
aliceryhl
This article seems like a good exploration of the ecosystem, and it came to
the same conclusions as I did.

------
perfmode
what’s the state of gRPC in rust?

last week, in research i discovered a few different implementations. no clear
winner.

~~~
hobos_delight
I've used tonic for a number of personal projects and quite liked it.

