rust
46 lines · 6 steps
Response compression in Axum with tower-http
Attach a tower-http CompressionLayer to an Axum router so JSON responses are gzip/brotli/zstd compressed selectively.
Explained by
highlit
1use axum::{
2 routing::get,
3 Json, Router,
4};
5use serde::Serialize;
6use tower_http::compression::{CompressionLayer, CompressionLevel};
7use tower_http::compression::predicate::{NotForContentType, SizeAbove};
8use tower_http::CompressionLevel::*;
9
10#[derive(Serialize)]
11struct Article {
12 id: u64,
13 title: String,
14 body: String,
15}
16
17async fn list_articles() -> Json<Vec<Article>> {
18 let articles = (1..=50)
19 .map(|id| Article {
20 id,
21 title: format!("Article #{id}"),
22 body: "Lorem ipsum dolor sit amet, ".repeat(64),
23 })
24 .collect();
25
26 Json(articles)
27}
28
29pub fn router() -> Router {
30 let predicate = SizeAbove::new(1024)
31 .and(NotForContentType::GRPC)
32 .and(NotForContentType::IMAGES)
33 .and(NotForContentType::const_new("application/wasm"));
34
35 let compression = CompressionLayer::new()
36 .gzip(true)
37 .br(true)
38 .zstd(true)
39 .no_deflate()
40 .quality(CompressionLevel::Precise(6))
41 .compress_when(predicate);
42
43 Router::new()
44 .route("/articles", get(list_articles))
45 .layer(compression)
46}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1A tower-http layer wraps every route so cross-cutting concerns like compression live outside handler logic.
- 2Compression predicates let you skip payloads that won't benefit — small bodies, already-compressed images, or gRPC.
- 3Enabling multiple encodings lets the layer negotiate the best one against each client's Accept-Encoding header.
Related explainers
rust
use std::cmp::Ordering; pub struct PrefixIndex { entries: Vec<String>,
Prefix search with binary partitioning in Rust
binary-search
sorting
case-insensitive
Intermediate
7 steps
go
package auth import ( "net/http"
Setting and reading secure session cookies in Go
cookies
session-management
security
Intermediate
6 steps
rust
use std::cmp::Ordering; use std::str::FromStr; #[derive(Debug, Clone, PartialEq, Eq)]
Parsing and ordering semantic versions in Rust
parsing
trait-implementation
ordering
Intermediate
8 steps
php
<?php namespace App\Http\Middleware;
Idempotent requests with Laravel middleware
idempotency
middleware
caching
Advanced
8 steps
go
package middleware import ( "net/http"
A maintenance-mode gate in Gin
middleware
atomic-flag
concurrency
Intermediate
8 steps
rust
use axum::{ extract::State, routing::{get, post, MethodRouter}, Json, Router,
Self-documenting routes in Axum
builder-pattern
closures
shared-state
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/response-compression-in-axum-with-tower-http-explained-rust-da11/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.