Install
openclaw skills install axum-code-reviewReviews axum web framework code for routing patterns, extractor usage, middleware, state management, and error handling. Use when reviewing Rust code that uses axum, tower, or hyper for HTTP services. Covers axum 0.7+ patterns including State, Path, Query, Json extractors.
openclaw skills install axum-code-reviewasync-trait in custom extractors.State<T>, not global mutable stateIntoResponse implementations, error typesRun in order. Do not write a finding until the step that applies has passed.
Version and edition on disk — Pass when: You have read the relevant Cargo.toml (crate or workspace root) and can state axum (and related tower/tower-http) versions and Rust edition. Then apply 0.6 vs 0.7+ or Edition 2024–specific checklist items only when that file supports them.
Per-finding evidence — Pass when: Each issue cites [FILE:LINE] from the current tree for the handler, router, layer, or type under review (not from memory, docs-only, or another branch).
Category check vs protocol — Pass when: For the finding type (routing conflict, extractor order, error leak, middleware order, etc.), you ran the matching checks from the review-verification-protocol skill (e.g. full handler signature for extractor order; surrounding error mapping before “raw error to client”). Then add the finding.
Output shape — Pass when: The report lines match Output Format below (severity + description).
Report findings as:
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
| Issue Type | Reference |
|---|---|
| Route definitions, nesting, method routing | references/routing.md |
| State, Path, Query, Json, body extractors | references/extractors.md |
| Tower middleware, layers, error handling | references/middleware.md |
/api/users, /api/orders).get(), .post(), not .route() with manual method matching)Json, Form, Bytes) are the LAST parameterState<T> requires T: Clone — typically Arc<AppState> or direct Clone derivePath<T> parameter types match the route definitionQuery<T> fields are Option for optional query params with #[serde(default)]FromRequestParts (not body) or FromRequest (body)async fn in trait impls (no #[async_trait] needed for FromRequest/FromRequestParts)State<T>, not global mutable staticsClone derived or manually implemented on state typeLazyLock from std (not once_cell::sync::Lazy or lazy_static!)IntoResponse for proper HTTP error codesResult<impl IntoResponse, AppError> pattern used for handlers-> impl IntoResponse capture all in-scope lifetimes by default; use + use<> to opt out of capturing request lifetimes when returning owned datatower-http used for common concerns (CORS, compression, tracing, timeout)#[async_trait] can migrate to native async fn in trait implsState<T> (race conditions)sqlx::Error returned to client)async-trait still used for FromRequest/FromRequestParts when native async fn works.get(), .post()tower-http::trace for request loggingonce_cell::sync::Lazy or lazy_static! used where std::sync::LazyLock workstower-http layers for common concernsutoipa or aide#[axum::debug_handler] on handlers — Debugging aid that improves compile error messagesExtension<T> for middleware-injected data — Valid pattern for request-scoped valuesimpl IntoResponse from handlers — More flexible than concrete typesRouter::new() per module, merged in main — Standard organization patternServiceBuilder for layer composition — Tower pattern, not over-engineeringaxum::serve with TcpListener — Standard axum 0.7+ server setupasync fn in FromRequest/FromRequestParts impls — async-trait crate no longer needed (stable since Rust 1.75)+ use<'a> on handler return types — Edition 2024 precise capture syntax for RPITstd::sync::LazyLock for shared static state — Replaces once_cell/lazy_static (stable since Rust 1.80)Complete Gates (before reporting findings) and load the review-verification-protocol skill for category-specific checks before any issue is final.