Is Rust suitable for building HTTP APIs?

Porting a serverless chatbot from Python to Rust

Notes on the experience of porting a small chatbot HTTP API from Python to Rust using the Rocket web framework.

Image for post
Image for post

Azure vs Google vs AWS

I have tried AWS Lambda, Google Cloud Functions, and Azure Functions, and have several personal utility functions running on both Google and Azure. Whilst I have been impressed with Google Cloud’s database products, they are still behind when it comes to the breadth of functionality in their serverless functions product. Google doesn’t support Rust and has no concept of custom runtimes like AWS and Azure do.

Creating a Python serverless bot

I have been writing Python for over 10 years, so it was the default choice to create a simple serverless bot. Azure has native Python support, the Basecamp API takes a simple HTTP POST, and Mailchimp has an official Python SDK.

Image for post
Image for post
Python bot posting our daily Mailchimp stats into Basecamp.

Why port to Rust?

Over Christmas I usually leave London to visit my family, however the change in COVID-19 rules meant that I could no longer leave the city. With some extra time, particularly in the quiet period between Christmas and New Year, I ended up spending several days playing around with Rust.

Reason 1: Fun and interesting

My main reason for porting from Python to Rust was that it was fun and interesting! I like Python (which sits at #3 in the “most loved” 2020 ranking) because it is easy to start writing code and you can get things done quickly. It also enforces a particular coding style which means more consistent layout, spacing, indenting, etc.

Reason 2: Portability

Neither AWS Lambda nor Azure Functions have native support for Rust, but they both support Custom Runtimes/Handlers. This allows you to build a generic web endpoint which, if it can handle to standard HTTP requests and return a standard HTTP response, can be executed by the platform.

Image for post
Image for post
The final 100% static, upx compressed binary. Only 2.5MB.

Reason 3: Developer tooling

I’m a vim user so the official rust.vim plugin gives me autocomplete and in-editor checks, but the output from Cargo (warnings and errors) is very helpful and pinpointing problems. rust-clippy is fun, too.

Challenges learning Rust

I wrote the Python bot in a few hours but it took me several days to get the Rust port working. This would be hard to justify if it wasn’t a learning project, but everyone gets faster with experience. I had to learn not just a new language but also how to properly cross-compile for a different platform. Here are my notes on some of those challenges:

Language challenges

There are several features which make Rust robust, safe, and correct, but require a shift in mindset if you’re used to other languages. For example, the way scoping and ownership works means you can’t just declare global variables and must consider when they go out of scope. Another example is the requirement to handle all return types/errors so that the program will never crash unexpectedly.

Web framework challenges

Rust is designed for system programming which means its really good at command line interfaces, programs that need to run robustly millions of times, or within memory/processing constrained environments like embedded systems. That doesn’t mean it’s not good for other use cases, but like most people don’t write webapps in C maybe Rust isn’t the best choice for building HTTP APIs?

Image for post
Image for post
Chatbot running the embedded web server framework, Rocket.

Build challenges

I run Manjaro Linux locally so compiling it for the same platform — x86_64-unknown-linux-gnu — was no problem. This is considered a Tier 1 Rust platform so it is officially supported and pretty much “guaranteed to work”.

Image for post
Image for post
Compiling totorobot for Linux musl on GitHub Actions.

Conclusions

This was a fun project to port to Rust. I was able to learn not just a new language but also a new approach to deploying software. Coming from the world of dynamic languages like Python, this is a different way of shipping code. The chatbot was small enough to not take too much time, but also touched several key concepts like making external HTTPS requests, building an API server, and writing basic unit tests. It’s cool to be able to package the entire executable in a tiny binary that can run on any system it is built for.

Co-founder https://console.dev — the best tools for developers. Researching sustainable computing at Uptime Institute. https://davidmytton.blog

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store