SlideShare a Scribd company logo
The Joy and Adventures of writing Rust for the web
Rust Web Development
$ whoami
★ Bastian Gruber
★ Software Engineer for ~ 15 years
★ Author of “Rust Web Development” (Manning)
★ Professional Rust experience ~3 years
★ Currently: Working on distributed Peer-to-Peer Systems in Rust
★ rustwebdevelopment.com
★ Mastodon: https://hachyderm.io/@bastian
★ Twitter: @recvonline
$ date
★ Todays talk: Rust Web Development
★ Why Rust in web development
★ How to get started
★ What to bring with you
★ Advantages
★ Things to consider
The slide for your CTO -
Why Rust for your microservice/API
➔ Thread-safe concurrency
➔ No memory-leaks*
➔ Saving $$$ on AWS
➔ Used by AWS, Microsoft, Google and others
➔ Excellent free learning resources
➔ Compiler enforces high standards and
correctness
But why you actually
want to write it in Rust
➔ The compiler is your pair-programmer who teaches you
➔ Excellent resources to learn and grow from
➔ Code standards are easily enforced through built-in tooling
➔ Documentation and testing is built-in
➔ High-standard third-party packages (crates)
➔ Compiles to a binary
➔ Freaking good type system :)
Rust 🧡 Web
…or does it?
Rust 🧡 Web
…or does it?
Rust 🧡 Web
…or does it?
Rust 🧡 Web
…or does it?
Rust 🧡 Web
…or does it?
Rust 🧡 Web
…or does it?
● Rust wants to be a systems programming languages
● Least amount of overhead
● So it decided against:
○ Adding a runtime to execute asynchronous code
○ Implement HTTP
○ Add a HTTP server to the library
● besides others…
Rust 🧡 Web
…or does it?
BUT, It brings the baseline to
● create TCP/UDP sockets
● write asynchronous code
TCP/UDP + async/await + Future trait
What do you need for asynchronous programming?
TCP behind the scenes
use std::net::TcpListener;
fn main() {
let listener =
TcpListener::bind("127.0.0.1:8080").unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
println!("stream accepted {:?}", stream);
}
(longer version over here)
That’s all hidden behind a framework, though
Example: axum
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(root));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn root() -> &'static str {
"Hello, World!"
}
Example: axum
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(root));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn root() -> &'static str {
"Hello, World!"
}
Async runtime: tokio
Example: axum
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(root));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn root() -> &'static str {
"Hello, World!"
}
Async runtime: tokio
async/await
Example: axum
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(root));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn root() -> &'static str {
"Hello, World!"
}
Async runtime: tokio
async/await
Web framework: axum
Example: axum
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/", get(root));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn root() -> &'static str {
"Hello, World!"
}
Async runtime: tokio
async/await
Web framework: axum
HTTP server: hyper
So, why then Rust and not NodeJS, Go?
No runtime overhead
No runtime overhead
Thread-safe async
pub fn main() {
let (tx, rx) = channel();
let x = Arc::new(RwLock::new(tx));
std::thread::spawn(move || {
x.read().unwrap().send(4u8).unwrap();
});
dbg!(rx.recv().unwrap());
}
error[E0277]: `Sender<u8>` cannot be shared between threads safely
--> src/main.rs:8:5
|
8 | std::thread::spawn(move || {
| ^^^^^^^^^^^^^^^^^^ `Sender<u8>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `Sender<u8>`
= note: required because of the requirements on the impl of `Sync` for
`RwLock<Sender<u8>>`
= note: required because of the requirements on the impl of `Send` for
`Arc<RwLock<Sender<u8>>>`
= note: required because it appears within the type `[closure@src/main.rs:8:24:
10:6]`
No runtime overhead
Thread-safe async
Rust compiler
No runtime overhead
Thread-safe async
Rust compiler
Standardised tooling
And so much more…
● gRPC: tonic
● Peer-to-Peer: libp2p-rs
● Websockets: tokio-tungstenite
● In-Browser: WASM
● HTTP requests: reqwest
● Parsing JSON (besides others): serde
Example: Simple API with background task
Live coding example…
Are there any downsides?
➔ Getting started with Rust takes longer
➔ Prototyping slower (strict compiler)
➔ You don’t want to go back to your previous language…
How to get started?
How to get started?
How to get started?
❖ Build something you like and use
➢ CLI
➢ Little helper web service
❖ Do the tokio tutorial
❖ Rust exercism
❖ Advanced reading
One more thing…
➢ Help creating types out of 3rd party APIs: Transform tools
➢ Use clippy to tidy up your code: cargo clippy -- -W clippy::pedantic
➢ Use cargo format rules to tidy up imports etc: Example .toml file
➢ Create documentation as part of your CI (GitHub example snippet):
name: Build Documentation
id: build_docs
uses: actions-rs/cargo@v1
with:
command: doc
args: --all --no-deps
Thank you!
Question?

More Related Content

PDF
Rust: Systems Programming for Everyone
PDF
The Rust Programming Language
PDF
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
PDF
Rust's Journey to Async/await
PDF
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
PPTX
From NodeJS to Rust
PDF
Rust Web Development With warp tokio and reqwest 1st Edition Bastian Gruber
PDF
Rust With async / .await
Rust: Systems Programming for Everyone
The Rust Programming Language
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Rust's Journey to Async/await
Apidays Paris 2023 - Forget TypeScript, Choose Rust to build Robust, Fast and...
From NodeJS to Rust
Rust Web Development With warp tokio and reqwest 1st Edition Bastian Gruber
Rust With async / .await

Similar to Rust Melbourne MeetUp - Rust Web Development (20)

PDF
Rust All Hands Winter 2011
PPTX
A Slice Of Rust - A quick look at the Rust programming language
PDF
Rust: Reach Further (from QCon Sao Paolo 2018)
PPTX
Introduction to Rust (Presentation).pptx
PDF
Practical Rust 1x Cookbook Rustacean Team
PPTX
PDF
Intro to Rust 2019
ODP
Rust Primer
PPTX
Rust 101 (2017 edition)
PPTX
Rust programming-language
PPTX
Rust presentation convergeconf
PDF
Rust Is Safe. But Is It Fast?
PPTX
Why Is Rust Gaining Traction In Recent Years?
PDF
Embedded Rust
PDF
Rust and Eclipse
PDF
Rusted Ruby
PDF
Why_safe_programming_matters_and_why_Rust_.pdf
PDF
Building Web APIs that Scale
PDF
JS Fest 2019/Autumn. Алексей Орленко. Node.js N-API for Rust
PPTX
MozillaPH Rust Hack & Learn Session 1
Rust All Hands Winter 2011
A Slice Of Rust - A quick look at the Rust programming language
Rust: Reach Further (from QCon Sao Paolo 2018)
Introduction to Rust (Presentation).pptx
Practical Rust 1x Cookbook Rustacean Team
Intro to Rust 2019
Rust Primer
Rust 101 (2017 edition)
Rust programming-language
Rust presentation convergeconf
Rust Is Safe. But Is It Fast?
Why Is Rust Gaining Traction In Recent Years?
Embedded Rust
Rust and Eclipse
Rusted Ruby
Why_safe_programming_matters_and_why_Rust_.pdf
Building Web APIs that Scale
JS Fest 2019/Autumn. Алексей Орленко. Node.js N-API for Rust
MozillaPH Rust Hack & Learn Session 1
Ad

Recently uploaded (20)

PDF
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
PPTX
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PPTX
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PPTX
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
PPTX
UNIT 4 Total Quality Management .pptx
PPTX
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
PPTX
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
PPTX
Internet of Things (IOT) - A guide to understanding
PDF
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
PPTX
bas. eng. economics group 4 presentation 1.pptx
PPTX
additive manufacturing of ss316l using mig welding
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PPTX
Foundation to blockchain - A guide to Blockchain Tech
DOCX
573137875-Attendance-Management-System-original
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
Evaluating the Democratization of the Turkish Armed Forces from a Normative P...
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
KTU 2019 -S7-MCN 401 MODULE 2-VINAY.pptx
UNIT 4 Total Quality Management .pptx
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
Internet of Things (IOT) - A guide to understanding
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
bas. eng. economics group 4 presentation 1.pptx
additive manufacturing of ss316l using mig welding
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
Foundation to blockchain - A guide to Blockchain Tech
573137875-Attendance-Management-System-original
Operating System & Kernel Study Guide-1 - converted.pdf
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
Ad

Rust Melbourne MeetUp - Rust Web Development

  • 1. The Joy and Adventures of writing Rust for the web Rust Web Development
  • 2. $ whoami ★ Bastian Gruber ★ Software Engineer for ~ 15 years ★ Author of “Rust Web Development” (Manning) ★ Professional Rust experience ~3 years ★ Currently: Working on distributed Peer-to-Peer Systems in Rust ★ rustwebdevelopment.com ★ Mastodon: https://hachyderm.io/@bastian ★ Twitter: @recvonline
  • 3. $ date ★ Todays talk: Rust Web Development ★ Why Rust in web development ★ How to get started ★ What to bring with you ★ Advantages ★ Things to consider
  • 4. The slide for your CTO - Why Rust for your microservice/API ➔ Thread-safe concurrency ➔ No memory-leaks* ➔ Saving $$$ on AWS ➔ Used by AWS, Microsoft, Google and others ➔ Excellent free learning resources ➔ Compiler enforces high standards and correctness
  • 5. But why you actually want to write it in Rust ➔ The compiler is your pair-programmer who teaches you ➔ Excellent resources to learn and grow from ➔ Code standards are easily enforced through built-in tooling ➔ Documentation and testing is built-in ➔ High-standard third-party packages (crates) ➔ Compiles to a binary ➔ Freaking good type system :)
  • 11. Rust 🧡 Web …or does it? ● Rust wants to be a systems programming languages ● Least amount of overhead ● So it decided against: ○ Adding a runtime to execute asynchronous code ○ Implement HTTP ○ Add a HTTP server to the library ● besides others…
  • 12. Rust 🧡 Web …or does it? BUT, It brings the baseline to ● create TCP/UDP sockets ● write asynchronous code TCP/UDP + async/await + Future trait
  • 13. What do you need for asynchronous programming?
  • 14. TCP behind the scenes use std::net::TcpListener; fn main() { let listener = TcpListener::bind("127.0.0.1:8080").unwrap(); for stream in listener.incoming() { let stream = stream.unwrap(); println!("stream accepted {:?}", stream); } (longer version over here)
  • 15. That’s all hidden behind a framework, though
  • 16. Example: axum #[tokio::main] async fn main() { let app = Router::new() .route("/", get(root)); let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } async fn root() -> &'static str { "Hello, World!" }
  • 17. Example: axum #[tokio::main] async fn main() { let app = Router::new() .route("/", get(root)); let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } async fn root() -> &'static str { "Hello, World!" } Async runtime: tokio
  • 18. Example: axum #[tokio::main] async fn main() { let app = Router::new() .route("/", get(root)); let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } async fn root() -> &'static str { "Hello, World!" } Async runtime: tokio async/await
  • 19. Example: axum #[tokio::main] async fn main() { let app = Router::new() .route("/", get(root)); let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } async fn root() -> &'static str { "Hello, World!" } Async runtime: tokio async/await Web framework: axum
  • 20. Example: axum #[tokio::main] async fn main() { let app = Router::new() .route("/", get(root)); let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } async fn root() -> &'static str { "Hello, World!" } Async runtime: tokio async/await Web framework: axum HTTP server: hyper
  • 21. So, why then Rust and not NodeJS, Go?
  • 23. No runtime overhead Thread-safe async pub fn main() { let (tx, rx) = channel(); let x = Arc::new(RwLock::new(tx)); std::thread::spawn(move || { x.read().unwrap().send(4u8).unwrap(); }); dbg!(rx.recv().unwrap()); } error[E0277]: `Sender<u8>` cannot be shared between threads safely --> src/main.rs:8:5 | 8 | std::thread::spawn(move || { | ^^^^^^^^^^^^^^^^^^ `Sender<u8>` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Sender<u8>` = note: required because of the requirements on the impl of `Sync` for `RwLock<Sender<u8>>` = note: required because of the requirements on the impl of `Send` for `Arc<RwLock<Sender<u8>>>` = note: required because it appears within the type `[closure@src/main.rs:8:24: 10:6]`
  • 24. No runtime overhead Thread-safe async Rust compiler
  • 25. No runtime overhead Thread-safe async Rust compiler Standardised tooling
  • 26. And so much more… ● gRPC: tonic ● Peer-to-Peer: libp2p-rs ● Websockets: tokio-tungstenite ● In-Browser: WASM ● HTTP requests: reqwest ● Parsing JSON (besides others): serde
  • 27. Example: Simple API with background task Live coding example…
  • 28. Are there any downsides? ➔ Getting started with Rust takes longer ➔ Prototyping slower (strict compiler) ➔ You don’t want to go back to your previous language…
  • 29. How to get started?
  • 30. How to get started?
  • 31. How to get started? ❖ Build something you like and use ➢ CLI ➢ Little helper web service ❖ Do the tokio tutorial ❖ Rust exercism ❖ Advanced reading
  • 32. One more thing… ➢ Help creating types out of 3rd party APIs: Transform tools ➢ Use clippy to tidy up your code: cargo clippy -- -W clippy::pedantic ➢ Use cargo format rules to tidy up imports etc: Example .toml file ➢ Create documentation as part of your CI (GitHub example snippet): name: Build Documentation id: build_docs uses: actions-rs/cargo@v1 with: command: doc args: --all --no-deps