Skip to main content

Module method_override

Module method_override 

Source
Expand description

HTTP method override — rewrite POST → PUT/PATCH/DELETE based on X-HTTP-Method-Override header or _method form field, so HTML forms can drive REST routes. See method_override::MethodOverrideLayer. HTTP method override — rewrite POST → PUT / PATCH / DELETE based on a hidden form field or header.

HTML <form> only emits GET or POST — no PUT, PATCH, or DELETE. The standard Laravel / Express convention is a hidden _method field (or X-HTTP-Method-Override header) carrying the intended verb; the server rewrites the request before routing.

§Why a tower Layer (not Router::layer)

axum 0.8’s Router::layer(...) runs the middleware AROUND the selected handler — after routing. To rewrite the method BEFORE routing dispatches, the layer must wrap the entire Router. Use tower::ServiceBuilder (or call MethodOverrideLayer::layer directly) to compose:

use rustango::method_override::MethodOverrideLayer;
use tower::ServiceBuilder;

let inner: axum::Router = axum::Router::new()
    .route("/posts/{id}", axum::routing::delete(destroy));

let app = ServiceBuilder::new()
    .layer(MethodOverrideLayer::default())
    .service(inner);

// app is a Service — pass to axum::serve(listener, app.into_make_service()).
<form method="POST" action="/posts/42">
    <input type="hidden" name="_method" value="DELETE">
    <button>Delete</button>
</form>

§Strategies

Tried in this order (whichever fires first wins):

  1. X-HTTP-Method-Override header (preferred — works for any Content-Type, cheaper than parsing the body).
  2. _method form field, when the request is application/x-www-form-urlencoded AND the body is small enough. Body-parse limit is configurable (default 64 KiB).

§Safety

  • Only POST requests are rewritten — never GET / HEAD / OPTIONS, regardless of what the client claims.
  • The override target must be in the configured allow-list. Default: PUT, PATCH, DELETE. Anything else is ignored.
  • The body is read once into memory when checking the form-field strategy — large uploads should use the header strategy and skip the body parse entirely.

Structs§

MethodOverrideLayer
Configuration for MethodOverrideService. Implements tower::Layer so it composes with ServiceBuilder.
MethodOverrideService
The wrapped service. Inspects each incoming POST for an override strategy and rewrites the method before forwarding to inner.