Book Image

Rust Web Programming - Second Edition

By : Maxwell Flitton
Book Image

Rust Web Programming - Second Edition

By: Maxwell Flitton

Overview of this book

Are safety and high performance a big concern for you while developing web applications? With this practical Rust book, you’ll discover how you can implement Rust on the web to achieve the desired performance and security as you learn techniques and tooling to build fully operational web apps. In this second edition, you’ll get hands-on with implementing emerging Rust web frameworks, including Actix, Rocket, and Hyper. It also features HTTPS configuration on AWS when deploying a web application and introduces you to Terraform for automating the building of web infrastructure on AWS. What’s more, this edition also covers advanced async topics. Built on the Tokio async runtime, this explores TCP and framing, implementing async systems with the actor framework, and queuing tasks on Redis to be consumed by a number of worker nodes. Finally, you’ll go over best practices for packaging Rust servers in distroless Rust Docker images with database drivers, so your servers are a total size of 50Mb each. By the end of this book, you’ll have confidence in your skills to build robust, functional, and scalable web applications from scratch.
Table of Contents (27 chapters)
Free Chapter
1
Part 1:Getting Started with Rust Web Development
4
Part 2:Processing Data and Managing Displays
8
Part 3:Data Persistence
12
Part 4:Testing and Deployment
16
Part 5:Making Our Projects Flexible
19
Part 6:Exploring Protocol Programming and Async Concepts with Low-Level Network Applications

Why is Rust revolutionary?

With programming, there is usually a trade-off between speed and resources and development speed and safety. Low-level languages such as C/C++ can give the developer fine-grained control over the computer with fast code execution and minimal resource consumption. However, this is not free. Manual memory management can introduce bugs and security vulnerabilities. A simple example of this is a buffer overflow attack. This occurs when the programmer does not allocate enough memory. For instance, if the buffer only has a size of 15 bytes, and 20 bytes are sent, then the excess 5 bytes might be written past the boundary. An attacker can exploit this by passing in more bytes than the buffer can handle. This can potentially overwrite areas that hold executable code with their own code. There are other ways to exploit a program that does not have correctly managed memory. On top of increased vulnerabilities, it takes more code and time to solve a problem in a low-level language. As a result of this, C++ web frameworks do not take up a large share of web development. Instead, it usually makes sense to go for high-level languages such as Python, Ruby, and JavaScript. Using such languages will generally result in the developer solving problems safely and quickly.

However, it must be noted that this memory safety comes at a cost. These high-level languages generally keep track of all the variables defined and their references to a memory address. When there are no more variables pointing to a memory address, the data in that memory address gets deleted. This process is called garbage collection and consumes extra resources and time as a program must be stopped to clean up the variables.

With Rust, memory safety is ensured without the costly garbage collection process. Rust ensures memory safety through a set of ownership rules checked at compile time with a borrow checker. These rules are the quirks mentioned in the following section. Because of this, Rust enables rapid, safe problem-solving with truly performant code, thus breaking the speed/safety trade-off.

Memory safety

Memory safety is the property of programs having memory pointers that always point to valid memory.

With more data processing, traffic, and complex tasks lifted into the web stack, Rust, with its growing number of web frameworks and libraries, has now become a viable choice for web development. This has led to some truly amazing results in the web space for Rust. In 2020, Shimul Chowdhury ran a series of tests against servers with the same specs but different languages and frameworks. The results can be seen in the following figure:

Figure 1.1 – Results of different frameworks and languages by Shimul Chowdhury (found at https://www.shimul.dev/posts/06-04-2020-benchmarking-flask-falcon-actix-web-rocket-nestjs/)

Figure 1.1 – Results of different frameworks and languages by Shimul Chowdhury (found at https://www.shimul.dev/posts/06-04-2020-benchmarking-flask-falcon-actix-web-rocket-nestjs/)

In the preceding figure, we can see that there are some variations in the languages and frameworks. However, we must note that the Rust frameworks comprise Actix Web and Rocket. These Rust servers are in a completely different league when it comes to total requests handled and data transferred. Other languages, such as Golang, have come onto the scene, but the lack of garbage collection in Rust has managed to outshine Golang. This was demonstrated in Jesse Howarth’s blog post Why Discord is switching from Go to Rust, where the following graph was published:

Figure 1.2 – Discord’s findings => Golang is spikey and Rust is smooth (found at https://discord.com/blog/why-discord-is-switching-from-go-to-rust)

Figure 1.2 – Discord’s findings => Golang is spikey and Rust is smooth (found at https://discord.com/blog/why-discord-is-switching-from-go-to-rust)

The garbage collection that Golang was implementing to keep the memory safe resulted in 2-minute spikes. This is not to say that we should use Rust for everything. It is best practice to use the right tool for the job. All these languages have different merits. What we have done in the preceding figure is merely display Rust’s merits.

The lack of need for garbage collection is because Rust uses enforced rules to ensure memory safety using the borrow checker. Now that we have understood why we want to code in Rust, we can move on to reviewing data types in the next section.