Evaluating Rust.

June 15, 2020

A look at setting using Rust for REST APIs and Embedded development.

Rust

This post documents my experience learning and working with Rust and why I choose to add it to my daily driver Python, javascript etc.

Python is also not typed although things like Python type hints and Fast API use these. In Rust, typing is strictly enforced. My first experience using types was a bit of c# although I didn't get the hang of it until using Typescript which has a great ecosystem

I've found working with types initially a bit confusing until a basic understanding of genrics is understood. Now disregarding the Javascript ecosystem. Once you have all the build tools set up typescript is pretty nice, most packages have a pre-existing typed version of their packages such as @types/express.

Development Velocity

In any case, a developer's initial velocity will feel quite low working with typed languages often struggling to figure out specific errors or how to extend a type using the previously mentioned generics.

But you will spend waay less time down the road catching undiscovered bugs, like undefined variables, unhandled errors or exceptions and other bad coding practices.

Once core functionality and workflow are established releasing new features or refactors becomes much easier. Plus your CLI's and web server start nearly instantly which makes spinning up a free Heroku Dyno from sleep is feel like a quick lambda

Strong Ecosystem

Cargo is the default package manager for Rust and is very easy to use. The communities are all great, often getting back to you very quickly.

Building Better API's: Moving away from Django

Django batteries included is a blessing and a curse, concepts that don't work well with a pure API such as using django forms for example in django-rest-frameworks to validate request REST validation is great piggybacking if you already have a Django codebase, but doesn't translate well outside of Django. Or trying to build anything custom in the Django Admin becomes laborious when the rest of your front end is written in React.

Previously I've written a React/Django Boilerplate called Rjango, which I spoke a PyCon India 2017 I've found GraphQL and Relay are pretty optional outside (Relay I don't even really recommend using) so I like to stick to stick with just REST nowadays.

The replacement API built in Rust: planet-express

My replacement for Rjango is a Rust Boilerplate called planet-express. It uses SQLx so your queries are written in SQL which is checked at compile time to ensure your SQL is compliant and your Database and Rust Types are always in line.

For the webserver, I've used Actix in conjunction wither PaperClip generate OpenAPI spec which can be used to generate client-side libraries for your API.

Embedded Development

I've been wanting to get into more IoT, Home Automation, Robotics/Drones and SCADA, MicroSats etc. I've got a few projects in mind. Although typically you will be working at a much lower level using Rust and I'm finding quick MVPs may still be easier in Arduino or MicroPython.

For hardware, I've primarily been using Raspberry Pi Zero WH and ESP32 (ESP32 and ESP8266) are often used to add WiFi or Bluetooth capabilities to Ardunio but can be programmed outright with their own set of GPIO pins, I2C, PWM, real-time clock support, etc.

For the various kids of hardware you might find there is usally a embedded-hal) implementation available.

A HAL is a hardware abstraction layer it provides a standardized way to interact with GPIO pins, i2c, PWM etc. One available for linx is linux-embedded-hal

Rust on Pi

Getting Rust to work on a Pi is much simpler with compiling happening in a docker container on your local machine and then being deployed over SCP, the binary on the Pi is is then executed using SSH with output piped to back to your local machine. When the SSH connection is closed the binary is stopped, this is easy to verify with say an LED from a Blink example (a common form of hello world in the embedded community). This all happens in this script which also only builds and copies the files if anything has changed. It will execute the binary regardless. I've got a few of these simple repositories up for personal reference and experimenting with the various packages. Here is the code for a rust based blink on a pi.

Rust on ESP32

To get the ESP32 to work with rust we used MabezDev's rust-extensa fork. Extensa being the ESP32 platform. He is very helpful on the esp-rs matrix channel.

Although atm I've been unable to get WiFi or Bluetooth working in a super streamlined manner. MabezDev linked to this project by reitermarkus which builds on the ESP-IDF the official ESP32 framework.

Closing

I've just scratched the surface. But I feel I've got a pretty good evaluation of what using Rust is like. As per usual when learning a new technology I'm trying to figure out when not to use as much as when to use it.