actix-web-extras

A small Rust crate that adds a Condition middleware to actix-web, letting you enable or disable any other middleware at runtime.

Library
Cargo
v0.1.0
0stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
15/100Needs Attention
Development Activity0
Maintenance0
Community4
Maturity56
Momentum0

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
45/100Fair
Architecture50
Code Quality55
Innovation35
Learning Curve40

actix-web-extras exists to fill one narrow gap in actix-web’s built-in middleware set: the ability to conditionally enable or disable a wrapped middleware without changing the shape of your .wrap() chain. Its single exported type, Condition<T>, takes a boolean flag or an Option<T> and produces a Transform that either runs the inner middleware or passes the request straight through, unifying the two possible response types with actix-web’s EitherBody.

The crate is intentionally minimal — one module, one struct, no macros, no extra dependencies beyond actix-web, futures-core, futures-util, and pin-project-lite. It targets a specific pain point (toggling Logger, Compress, NormalizePath, DefaultHeaders, or custom ErrorHandlers based on an environment variable or config flag) rather than trying to be a general-purpose extension pack, despite the broader ambition suggested by its name.

What You Get

  • A Condition<T> struct implementing actix-web’s Transform and Service traits for any wrapped middleware type T
  • Two constructors: Condition::new(bool, transformer) for flag-based toggling and Condition::from_option(Option<transformer>) for building directly from optional config
  • Response body unification via actix-web’s EitherBody, so the enabled and disabled code paths type-check as a single Service implementation
  • Drop-in compatibility with actix-web’s own middleware (Logger, Compress, NormalizePath, DefaultHeaders, ErrorHandlers) with no changes required on their side

Common Use Cases

  • Environment-gated middleware - an operator enables NormalizePath only when a NORMALIZE_PATH env var is set, without branching the App::new() construction code itself
  • Config-driven feature toggles - a service enables or disables custom ErrorHandlers or Compress based on an Option<T> field already present in its config struct
  • Test vs. production middleware stacks - a test build disables logging or compression middleware while keeping an identical .wrap() chain shape to production
  • Gradual middleware rollout - a team wraps a new middleware in Condition behind a flag so it can be flipped on for a subset of environments before full adoption

Under The Hood

Architecture The crate is a single-module library exposing one middleware type, Condition<T>, under middleware::. It implements actix-web’s Transform/Service trait pair, holding an Option<T> set once at construction. new_transform branches exactly once — at app-build time, not per request — into a boxed future that either drives the wrapped transformer’s own new_transform and returns ConditionMiddleware::Enable, or immediately resolves to ConditionMiddleware::Disable. Per-request dispatch matches on that two-armed enum in poll_ready/call, and a pin_project!-generated ConditionMiddlewareFuture enum mirrors the same structure so no dynamic dispatch or extra allocation happens on the hot path. There is effectively one abstraction in the whole crate — changing it means rewriting the crate.

Tech Stack Pure Rust (edition 2018) built directly against actix-web 4’s Transform, Service, and EitherBody primitives with no wrapper crates in between. futures-core/futures-util supply LocalBoxFuture and FutureExt::boxed_local; pin-project-lite’s pin_project! macro safely projects the two-armed future enum without unsafe code. Dev-dependencies (actix-service, actix-rt) are used only inside the test module to build an actix_web::test harness — there is no build tooling beyond Cargo and no framework layer beyond actix-web itself.

Code Quality The crate ships a real test module exercising all four branches (enabled/disabled × new/from_option) against actix-web’s own test::call_service harness, asserting header side effects to confirm the correct middleware path ran. Error handling stays generic over the wrapped middleware’s own Err type rather than introducing a new error type, so failures propagate unchanged. Naming mirrors actix-web’s own middleware conventions (Condition, ConditionMiddleware, ConditionMiddlewareFuture), the public API is fully typed with no unsafe blocks, but no CI configuration or linter config ships in the repo beyond an inline clippy allow attribute in the tests.

API Design One import path (actix_web_extras::middleware::Condition) and two constructors covering the two natural entry points — a bool flag or an Option — compose with .wrap() exactly like any other actix-web middleware, requiring no new mental model beyond “you’re wrapping a wrapper.” Doc comments carry runnable examples for both constructors directly in the source, which is the entire public documentation surface; there is no separate docs site or guide beyond a one-line README.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search