🦀 New book release: Wrapping handlers with middleware + two new appendices + a brand-new cover

Chapter 10 is here with Tower middleware and a DynamoDB-backed rate limiter, plus new appendices on running Axum on Lambda and deploying with GitHub Actions. And the book got a new cover!

If you are reading this is probably because you bought a copy of the e-book “Crafting Lambda Functions in Rust” by Luciano Mammino and James Eastham: A practical guide on how to build efficient, sustainable, cost-effective serverless AWS solutions with the Rust programming language. If not, and this topic sounds interesting to you, check out the book website at rust-lambda.com.

Chapter 10 is here! Middleware for Serverless Rust 🧩

Hello again, fellow Rustaceans 🦀

It took us a while, but we're finally back and excited to share with you a big release.

This one is about the code that is not your business logic: the tracing setup, the rate limits, the error mapping, the headers, and all the other bits that end up copy-pasted into every handler until nobody remembers which function has the latest version.

If you have ever wished your Lambda handlers could go back to doing one thing, this chapter is for you.

TLDR; for the busy ones:

  • Chapter 10 is out: Tower middleware for Lambda, from the Service and Layer basics to a DynamoDB-backed rate limiter and a reusable observability layer

  • Two new appendices: running an existing Axum service on Lambda, and a CI/CD blueprint for GitHub Actions with OIDC

  • New cover: fresh artwork for the light and dark editions, and the ePub finally has a cover too

  • Roadmap update: Chapter 11 is now Authentication and authorization, and the book is at 10 of 11 chapters plus 4 appendices

Alright, do you want the full details? Let's jump in!

Chapter 10 is here! Wrapping Handlers with Middleware 🧩

Here is a fact that is not as widely known as it should be: the Rust runtime for Lambda is built on Tower, the same middleware abstraction used by Axum, Hyper, and Tonic. That means every Lambda handler already comes with a fully featured middleware engine. No extra framework needed.

Sending requests through middleware!

Chapter 10 puts that foundation to work. We cover:

  • Service and Layer — the two Tower traits, explained with small standalone examples you can run locally (no-op, logging, response headers, error recovery)

  • The four moves — inspect, transform, short-circuit, and recover, plus why layer order changes what each layer gets to see

  • Ok(response) vs Err(...) — the one rule that keeps API Gateway from turning your carefully shaped 429 into a generic 500

  • Testing without Lambda — exercising a whole middleware stack with oneshot(), no deploy required

  • A real rate limiter — a fixed-window, DynamoDB-backed limiter with atomic counters, TTL cleanup, X-RateLimit-* headers, customisation hooks, and a clear fail-open / fail-closed policy

  • A design checklist — the questions to ask before writing your own layer

  • Observability as middleware — the OpenTelemetry instrumentation from Chapter 9 moves into a reusable layer, so every request is traced and flushed, even the ones rejected before the handler runs

As always, everything happens inside our trusty URL shortener. The rate limiter protects the management endpoints (POST /links and GET /links) while the public redirect stays untouched, and by the end of the chapter all three HTTP functions share the same two-layer stack: observability on the outside, rate limiting on the inside, and a handler that only does its job.

We hope this chapter saves you from the "which function has the good version of this code?" archaeology we have all done at some point!

Two new appendices 📎

Two topics that were on the roadmap as full chapters turned out to fit better as appendices, so they are both in this release.

Appendix C: Hosting Existing Rust HTTP Services on Lambda

Sometimes you do not start from scratch. This appendix shows how an axum::Router can be passed straight to lambda_http::run with no glue code, how to keep the same binary runnable on a local TCP port, and what you trade away when you pack a whole API into one function (IAM scope, scaling, per-route metrics, payload and timeout limits). It closes with the AWS Lambda Web Adapter for servers that cannot use lambda_http at all.

Appendix D: Integrating with GitHub Actions

A complete CI/CD workflow for a Rust serverless application: OIDC authentication to AWS instead of long-lived keys, Cargo caching, cross-compilation for ARM64, separate test and deploy jobs, and a non-interactive SAM deployment. There are notes on adapting the same pipeline to CDK and Terraform.

Other improvements across the book 💅

A brand-new cover

Our mascot Lambdino has moved from a plain gradient to a proper mountain top. The light edition gets a daytime scene and the dark edition a sunset, and the ePub now ships with a cover as well (it never had one before, sorry about that!).

The new book covers (light and dark variants). What do you think?!

Roadmap and structure

Chapter 11 is now Authentication and authorization and is in progress, followed by closing notes. The former planned chapters on hosting HTTP services and GitHub Actions became Appendices C and D, and Lambda extensions is no longer a standalone chapter (the topic is covered where it matters in Chapters 1 and 9). The preface has been updated to match.

📦 How to get the new release

If you already have a copy of Crafting Lambda Functions in Rust, grabbing the latest release is easy!

  1. Head over to Gumroad, log in, and open up your product library.

  2. You'll see a list of all your purchased products. Look for "Crafting Lambda Functions in Rust (e-book)".

  3. Click on it, and voilà! You'll find all the updated download links right there.

If you have the Gumroad mobile app the process should be similar!

All updated code examples are also available in our code repository, so you can dive into the latest examples straight away. The chapter 10 workspace includes the full rate limiter with its unit tests and the runnable middleware examples.

If you hit any snags along the way, reach out, we're here to help!

🔮 What's next: Chapter 11 (Authentication and authorization) 👀

With middleware in place, the natural next step is to put it to work on the question every API eventually has to answer: who is calling, and what are they allowed to do?

Chapter 11 will cover authenticating callers and authorising access to Lambda-backed APIs, building on the layers from Chapter 10. Once that lands, the URL shortener will finally be able to tell its users apart, and the rate limiter will get a better key than an IP address.

Watch this space!

🫶 We need your help

This book is a project of love that we build off-hours, so any help you can give is golden.

If you want to contribute, here are a few high-impact ways:

Tell us what works and what does not. If you spot typos, confusing sections, or places where you think "this could be explained better," please tell us.

Show us your Rust and Lambda creations. If you are building something with Rust on Lambda, we would love to see it. Share your projects in our Discord community or reply with a short description and links. With your permission, we might feature some of them as examples or case studies.

Join the conversation on Discord. That is where we bounce ideas, discuss patterns, and occasionally rant about tooling. If you are not there yet, this is your invitation to join, say hi, and tell us what you would like to see more of in the book.

Thank you again for reading, for experimenting with Rust on Lambda, and for keeping us accountable and motivated to make this book the most practical guide we can.

Happy building! 🦀

— Luciano & James

Reply

or to participate.