16 comments

[ 6.0 ms ] story [ 46.4 ms ] thread
In January I built a personal project on the web with Rust and had the positive experience I was hoping for. The efficiency of execution plus the cleanliness and memory safety of a modern language was the draw.

It took me a week of battling with the compiler to understand what I was doing, but afterwards it felt fairly natural.

My biggest hurdle was I went all in on async (the bikesheded, nightly feature). But a pet peeve of mine is that desktop apps were all async in the 90s and here we have webservers hoarding processes and threads, simply waiting on IO.

I quickly ran into the limits of Rust's async ecosystem. Hyper is an excellent library but there wasn't a webserver framework on top of it at the time. Now there is warp, so I intend to switch over to that from having rolled my own, but I hear some rumbling on reddit that it can lead to compiled size explosion, so gonna watch out for that.

For sql, I'm using mysql-async, but it seems like a single persons passion project. It's quite painful because even with the good libraries (serde) it feel broken to do so much hand writing of sql given the rich type information available in my structs. Everyone seems to use diesel but afaict it's incompatible with the async approach. This is my only real pain point right now.

The whole async ecosystem is still nightly and in flux all the time. Though, amazingly, it's worked quite well. It's clear the community has rallied behind it as most projects are on the bleeding edge. But hiccups happen such as mysql-async not yet supporting the new, nearly-stable version of futures.

Another pain point i've run into is there aren't great crypto libraries. Some very incomplete pure rust stuff. Some poorly documented wrappers of c stuff.

Finally, a third party web api I'm interfacing with doesn't have a rust library so I had to roll my own.

For other random needs I've been surprised by how often I find a great library. AWS libraries, for example, are surprisingly good.

My conclusion is that for web backends rust isn't plug-and-play yet (especially if you want to go all async). But it's pretty darn close.

And yeah, it's crazy fast. Like working in Modern C++ but with iron clad memory safety.

I think backend web development except for protocol and server is inherently a text processing work:

1. Parse http request map them to language data structures.

2. Do some processing.

3. Convert data structures to json or HTML or blob as response.

Given this paradigm language stronger in text processing like lisp, perl, python, Ruby are easier and more productive. Rust and Go in my view are still not strong in this area, therefore might not be as strong in backend web programming.

But people have built very powerful web application in C++, Go, C and some even in Rust. So it is possible and I will be very happy that development of web application in Rust might develop powerful libraries for text precessing, which will make it more productive with memory safety.

So go ahead, if possible share your development experience.

I am still busy learning lisp, hope can find time to look into other languages.

I personally don't see it that way. Usually the bottleneck is the database.
Probably you might be right, in my view database is just for persistence, most of the time text processing happens in the application or framwwork. Database is a very well understood system so reading and writing to it using language drivers can be optimized. Indeed go and rust both have excellent drivers for PostgreSQL, but still developing web application in them is not easy due to inherent text processing requirements and dealing with http request/response in json, html, xml, protocol buffers, blobs and various mime-types.
What text processing? You mean templating? Those a rather well solved problems, although the Go templates are a bit odd.

But Go, Rust, Scala and the like blow those dynamic typed languages out of the water when it comes to APIs.

For example. If you want a number to be a positive integer you would write a Go struct containing a uint. That's all.

Want it to be optional Rust or Scala have an optional Type.

If someone submits a negative number or a float the framework automatically generates an error message.

In ruby for example you would have to write a bunch of validations per hand and a bunch of tests too, to check if those work.

Writing APIs in Go is like half the work compared to Ruby or god forbid PHP.

Have not tries Node yet but i assume it to be on a level with Ruby.

It's not a solved problem in rust or go. It's still easier to write understandable text processing code in Python, Perl, Ruby, lisp than in Go or Rust.

Also for web backend Go, Rust cannot close the gap with Python or Ruby or lisp easily. Rust and Go are strong in their own domain writing web backend is not one of them. It does not mean one cannot write, it's just a lot of work.

When dealing with MIME types or REST or HTML or XML etc. dynamic typed languages are still easy, readable with reasonable performance. Only when one wants high performance, will go through the path of writing API in go or rust.

Go is already being used in lots of microservices.
If you’ve got 300 engineers and performance problems then that’s a great idea.

If you have 3 engineers and a little seed funding then building Go microservices to serve a web app is probably just pissing away VC money.

Just because people do it doesn’t make it a good idea.

> If you want a number to be a positive integer you would write a Go struct containing a uint. That's all.

Uint is a specific machine type, not an abstract positive integer type. So if you want a positive integer in Go you are fucked. If you try to use uint for that you have to carefully handle a whole bunch of edge cases. It's only in some dynamically typed languages a positive integer will be a positive integer and in better ones numeric operations will even be separate from string operations, so doing APIs will be significantly safer than in Go.

> In ruby for example you would have to write a bunch of validations per hand and a bunch of tests too, to check if those work.

In idiomatic Ruby it's more like one line in the struct definition vs one line in the model definition. ActiveModel and dry-validations have battle tested single line validations for this with automatically generated error messages.

Most modern web frameworks will deliver requests to your application already parsed into whatever kind of data structure you want. Text processing is a very small part of backend development.
This reads a bit like having (maybe unconsciously) picked Rust first and then coming up with arguments to rationalize that choice. Which is completely fine, especially for a small personal project. It's just weird that the article spends so much time discussing the pros and cons of various languages and then says "oh BTW, no GC'd language is acceptable".
- async IO - fast and safe parsing - JHipster style end to end code generation off a data model

My wish list. Been noodling at making a Python port of JHipster, swapping in Rust parsers.

All libraries need to make async IO a priority.

Go is as performant for web backend CRUD as Java and .Net in my experience, despite being compiled. I am auditing Rust's performance but in the meantime changing the system architecture through things like message queues and/or in memory databases makes the performance increase by leaps and bounds.
How exactly were you planning on using C++ for web? I have looked into this before, and concluded it's basically impossible. No matter what you do, you have to end up implementing a lot of the HTTP protocol because there aren't any off the shelf frameworks like Spring and Rails.