Rust is a hard way to make a web API

Interesting article and discussion on HackerNews:
https://news.ycombinator.com/item?id=25798008

Meh. Yet another "hurr durr rust hard" article. Cf. this:

But for most web applications, they’re not the most important concerns.

Quite an ironic assertion from an author who literally just complained about authentication. I like my web APIs race-free (that even Go can't guarantee!), and type safe by-design, for example.

About 3 years ago, I built a somewhat complicated production-ready web backend with Rust. It used libsodium for crypto, authenticated with Facebook just fine based on the official API docs, and, wait for it, used Stripe for payments, because there is a Stripe client crate.

Complaining about the lack of resources that are a crates.io search away is not a great way to criticize a language and an ecosystem.

4 Likes

From the article:

But Rust’s memory rules aren’t more secure than Node.js’s or Python’s. Your web application written in Rust isn’t going to be systematically more or less secure than an application in Python or Ruby.

Actually a web server written in Rust just might be more secure, depending on how the code was written, because of the excellent and extremely strong static type system (surpassed only by the likes of Idris I'd say due to its support for dependent typing).
So that argument is fallacious.

The article also claims this:

High-level languages with garbage collectors pay a performance penalty in exchange for generally dodging this whole class of exploits and bugs.

This misses an important point about runtime GC: you not only pay a runtime penalty in terms of speed that grows superlinearly with RAM usage, but you also get a 4-6 times memory overhead compared to a non-GC language.

Now for small web servers this isn't likely to matter. But things like performance don't matter until they do. And at that point you've got one hell of a problem, because of organic growth of the program. I've seen first-hand the amount of effort it can take to tune the JVM in order to get even semi-acceptable performance out of a 1MSLOC* Java code base.

Then there's this:

Heck, if you ask some people, Rust is less secure than a GC’ed language for web apps if you use any crates that have unsafe code - which includes Actix, the most popular web framework, because unsafe code allows things like deferencing raw pointers.

This is an appeal to authority, a well-known kind of fallacy.

Next the author claims:

The Rust ecosystem is not web-centric

This makes me wonder if the author has seen the absolutely massive amounts of effort put into both client side and server side. What's been accomplished to date in less than 6 years is nothing short of amazing. A couple of highlights: WASM support, NodeJS integration via at least 2 avenues (WASM as well as neon), various web server libraries (not frameworks, but libraries. The latter is a superior approach to due the lack of flexibility of frameworks), integration for lots of DBs, etc.

The Juniper crate invites n+1s

This entire paragraph talks about Juniper and how it makes things difficult for the backend.
A couple of notes: if that is inherent in how GraphQL servers work, then we can stop discussing this, no other language could do things differently. If it isn't inherent, however, then it's a potential design issue with Juniper. That means that the issue is with the choices the author has made: choosing Juniper as a GraphQL server, or choosing GraphQL in the first place. As the author himself points out, there are viable alternatives.

The word is that GraphQL works really well with non-SQL databases which can serve these sorts of requests fast. I’m sure that there’s some special database used internally at Facebook that’s incredible in combination with GraphQL, but the rest of industry is pretty attached to Postgres and its ilk, for good reason.

Postgres support for Rust is excellent, so I'm not sure what the author is even trying to say here.

*The point I'm making with this metric is that rewriting the code in a more performant language wasn't feasible in the slightest.

2 Likes

Hmm... I just grabbed Rocket and postgres and made a web server with REST API.

I guess nobody told me it was hard.

I'm very sure my Rust web API is a lot more robust and secure that my previous efforts using node.js. What with all the memory safety and type checks going on.

3 Likes

That's not inherent to GraphQL, but really due to how the juniper crate is designed. Basically the issue is that juniper provides an API which invites you to resolve each field separately. So if you have an Vec<SomeChild> you will likely resolve each child in own call.
Having that written: Juniper also exposes API's to workaround that issue, but they could definitively do a better job in at least mentioning this potential issue. For anyone looking into a possible solution, I've written wundergraph which simplifies the integration of diesel and juniper, while working around those N + 1 problems.
(I should probably add a word of warning here: Wundergraph does currently not compile on the latest stable release (1.49), due to a rustc regression. If you want to checkout that crate, use an older version (like 1.48))

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.