šŸ™ tako

Plugins

The tako-rs-plugins crate — bundled middleware and plugins, the plugins feature flag, and how plugins differ from middleware.

Plugins

tako-rs-plugins is the crate that ships Tako's concrete middleware and plugins. The traits (IntoMiddleware, Next, TakoPlugin) live in tako-rs-core; this crate hosts the ready-to-use implementations, re-exported through the umbrella crate under tako::middleware::* and tako::plugins::*.

Middleware vs. plugin

Tako has two extension mechanisms, and the catalog uses both. Knowing which is which tells you how to register it.

MiddlewarePlugin
TraitIntoMiddlewareTakoPlugin
Shapea Fn(Request, Next) -> Future<Response> wrapping one handlersetup(&self, router) that installs onto the router
Registerrouter.middleware(x.into_middleware()) or route.middleware(...)router.plugin(x) or route.plugin(x)
Typical jobinspect / transform a single request-responseinstall middleware, add routes, register state

A middleware sits directly in the request path: it gets a Request and a Next, and either calls next.run(req).await or returns early. A plugin is a setup step — its setup hook can register middleware and mount extra routes or state. That is why the metrics plugin can add a /metrics scrape endpoint, and why CORS/compression/rate-limiting are plugins: they wire several pieces onto the router at once.

use tako::middleware::IntoMiddleware;
use tako::middleware::request_id::RequestId;
use tako::plugins::cors::CorsBuilder;

// Middleware: build it, convert it, register it.
router.middleware(RequestId::new().into_middleware());

// Plugin: build it, register it directly.
router.plugin(CorsBuilder::new().build());

Both can be scoped: Router::middleware / Router::plugin apply globally, while Route::middleware / Route::plugin apply to a single route.

What's bundled

Middleware (tako::middleware::*):

  • Auth — basic_auth::BasicAuth, bearer_auth::BearerAuth, api_key_auth::ApiKeyAuth, jwt_auth::JwtAuth. See Authentication.
  • Security — csrf::Csrf, session::SessionMiddleware, security_headers::SecurityHeaders, body_limit::BodyLimit. See Security.
  • Observability — request_id::RequestId, upload_progress::UploadProgress, access_log::AccessLog, traceparent::Traceparent. See Metrics & Observability.
  • Cross-cutting — etag::Etag, timeout::Timeout, tenant::Tenant, circuit_breaker::CircuitBreaker, problem_json::ProblemJson, healthcheck, plus feature-gated ip_filter::IpFilter, hmac_signature::HmacSignature, and json_schema::JsonSchema.

Plugins (tako::plugins::*):

  • cors::CorsBuilder, compression::CompressionBuilder, rate_limiter::RateLimiterBuilder, idempotency::IdempotencyBuilder — see Traffic.
  • metrics::{PrometheusMetricsConfig, OtelMetricsConfig} — see Metrics & Observability.

Enabling the set

Most of the middleware (auth, CSRF, sessions, security headers, request ID, body limit, upload progress) compile without any extra flag. The plugins — CORS, compression, rate limiter, idempotency — require the plugins feature:

[dependencies]
tako-rs = { version = "2", features = ["plugins"] }

A few capabilities layer on top of plugins:

FeatureAdds
pluginsCORS, compression (gzip/brotli/deflate), rate limiter, idempotency
zstdzstd compression in the compression plugin
metrics-prometheusPrometheus metrics export (pulls in signals)
metrics-opentelemetryOpenTelemetry metrics export (pulls in signals)

metrics-prometheus and metrics-opentelemetry both imply plugins and signals. See the feature reference for the complete graph.

Stores

Stateful middleware — sessions, rate limiting, idempotency, JWKS rotation, CSRF — keep their persistence behind the tako_rs_plugins::stores traits. The default backend is an in-process scc::HashMap; companion crates can implement the same traits to move state into Redis or Postgres without changing any handler or middleware code.

For how the chain is assembled and ordered, start with the middleware model.

On this page