In the beginning of time RPC (Remote Procedure Calls) was the standard way of communicating between remote services. Some time passed and REST (REpresentational State Transfer) took over as the king. REST and JSON became popular because they made it easy to understand the communication between clients and servers, since JSON is easy for humans to read. With the rise of Microservices and systems that are increasingly chatty, JSON became a considerable overhead. Transmiting data in a human read...| ncona.com
Learning about computers| ncona.com
gcloud-sdk At the time of this writing, there is no official Google Cloud library for rust. Google started working on google-cloud-rust, but it’s still under development. The most popular alternative seems to be gcloud-sdk, so that’s what we’ll be using. This SDK uses tonic to build the gRPC clients, so a little familiarity with tonic, might be helpful. Since we are going to focus on the Storage API, we need to add this dependency to our Cargo.toml file: 1 gcloud-sdk = { version = "0.27...| ncona.com
A few years ago I wrote an article explaining Protocol Buffers, gRPC, and showing how to use them with Java. In this article, I’m going to show how to build the same server and client, but this time with Rust. Project structure There are going to be 3 parts for our example: Proto files Server Client We’ll have a root folder and then a folder for each part: 1 2 3 4 / ├── client ├── protos └── server| ncona.com
In this article, we are going to show how to get started with Geospatial data in PostgreSQL. More specifically, we are going to learn how to store spatial information (e.g. Coordinates in a map) and how we can index and perform searches on this data (e.g. Find all coordinates inside a given area). Installing PostGIS PostGIS is an extension of standard PostgreSQL that allows us to work with geospatial data. This means, if the extension is not present, we won’t have these capabilities. To che...| ncona.com
In this article, we are going to learn how to write software that uses configuration files using ESP-IDF. Kconfig Kconfig is the configuration system used by the Linux kernel and by ESP-IDF. It allows management of project settings through a structured and hierarchical menu system. It allows developers to write configuration files that specify the available configuration options for a piece of software.| ncona.com
In this article, we are going to explore how the clipboard works when using different tools inside a terminal and how we can configure these tools so we get and intuitive experience. Linux The most basic example of using the clipboard would be using it directly from the operating system. Most Linux distributions come with a built-in clipboard. This clipboard works as a temporary data storage that can hold a single item. To add an item to the clipboard, we can select it, right click it and sel...| ncona.com
Internationalization is the process of making a website that is adaptable to different locales (regions or languages). Translation is a large part of it, but there are other aspects, like date formatting, for example. There is no single standard way to do internationalization. In this article we’ll learn the approach I chose, but there are other ways to achieve a similar result. URLs To make an internationalized app SEO friendly, it’s recommended to have locale-prefixed URLs. This means, ...| ncona.com
In a previous post, we learned about asynchronous programming with Tokio. This time, we are going to use Axum to build a server that uses Tokio as runtime. Hello world Creating a simple server with Axum only requires a few lines: 1 2 3 4 5 6 #[tokio::main] async fn main() { let app = Router::new().route(| ncona.com
I’m working a project that uses Firestore, so I’m using the firestore crate to help me interact with my database. There are two examples showing the use of transactions in the source code: transactions.rs read-write-transactions.rs There are some parts of those examples that are a little confusing, so I’m writing this article to try and shed some light. I was not the only one confused by this, and luckily someone brought this up in a Github issue before I had to.| ncona.com
Unrecoverable errors These errors are a sign that the developer made a mistake. An example of this, could be trying to access an index that is out of bounds. For example: 1 2 3 4 5 6 7 8 fn get_number() -> usize { return 5; } fn main() { let numbers = [1, 2]; println!(| ncona.com
I’m building a little web server with Rust and as part of it, I’m going to need to send some e-mails to my users. I found a few services that offer an e-mail API with a free tier, and decided to go with Brevo. Authenticating our domain In order for our e-mails to reach our users’ inboxes, we need to correctly configure our DKIM and DMARC records so they can be used by Brevo. We can’t authenticate e-mails from free email providers like Gmail. So, before we can authenticate our domain, ...| ncona.com
I was reading some networking code and I stumbled into something that looked similar to this: 1 2 3 4 5 typedef struct __attribute__((__packed__)) { uint8_t a; uint16_t b; uint32_t c; } some_t; I had no idea what __attribute__((__packed__)) meant, so I did some digging and learned a bit about data alignment.| ncona.com
I have in the past written an article explaining how to send HTTP requests with Arduino. This time we’re going to learn how to do it using ESP-IDF. This article is the result of my learnings from analyzing the official ESP HTTP client example. ESP-NETIF ESP-NETIF is ESP32’s abstraction for TCP/IP. It’s not too complicated to use, but it’s somewhat verbose. All applications that use it need to start by calling: 1 esp_netif_init(); This function should be called only once, when the appl...| ncona.com
If you are interested in learning about asynchronous programming in more depth, I recommend reading Asynchronous Programming in Rust. Asynchronous programming When we run code that makes network requests, these request are sent through the network. Sending the request and waiting for the response is done by the network peripheral and doesn’t require the CPU. This means, the CPU is free to do other things while it waits. Code written synchronously will send a request and then block the threa...| ncona.com
One of Rust’s most praised features is how it makes concurrent programming safe. In this article we are going to learn some ways to do concurrent programming and explain how Rust makes them safe compared to other programming languages. Working with threads We can start new threads with thread::spawn: 1 2 3 4 5 6 7 8 9 10 use std::thread; use std::time::Duration; fn main() { thread::spawn(|| { println!(| ncona.com
Rust is considered safe because it makes sure variable ownership is managed correctly in our code. In the most basic case, Rust enforces these rules: Each value in Rust has an owner. There can only be one owner at a time. When the owner goes out of scope, the value will be dropped. The problem is that there are some scenarios where we need to break these rules. This is where smart pointers help us. What are smart pointers? Smart pointers are structs that manage some internal data. They are ca...| ncona.com
Rust has a mechanism called borrow checker that makes sure references are not used when they are not valid anymore. The borrow checker uses lifetimes to do its job internally. Let’s look at a simple example where the borrow checker detects a possibly invalid reference: 1 2 3 4 5 6 7 8 9 10 fn main() { let r; { let i = 1; r = &i; } println!(| ncona.com
In this article, we are going to learn how to write and run tests for Rust. Unit tests Rust made the interesting decision that unit tests should be written in the same files as the code under test. Let’s imagine we have a module with a function named add: 1 2 3 pub fn add(left: i64, right: i64) -> i64 { left + right } If we want to test that function, we would modify the file to look like this:| ncona.com
Rust is a relatively new programming language that promises to be as fast as C, but less complex and error prone. Rust compiles directly to machine code, so it doesn’t require a virtual machine. This makes it faster than languages like Java or Python. It also doesn’t use a garbage collector, which makes it faster and more predictive than other compiled languages like Golang. On top of speed and predictability, Rust also promises a programming model that ensures memory and thread safety, w...| ncona.com
To make HTTP and HTTPS requests from an Arduino board, we need to first install the ArduinoHttpClient library: 1 arduino-cli lib install ArduinoHttpClient Once we have the library, we can use it to make requests:| ncona.com