- Home
- Skills
- Windmill Labs
- Windmill
- Rust Backend
rust-backend_skill
- HTML
15.8k
GitHub Stars
1
Bundled Files
2 months ago
Catalog Refreshed
4 months ago
First Indexed
Readme & install
Copy the install command, review bundled files from the catalogue, and read any extended description pulled from the listing source.
Installation
Preview and clipboard use veilstrat where the catalogue uses aiagentskills.
npx veilstrat add skill windmill-labs/windmill --skill rust-backend- SKILL.md11.5 KB
Overview
This skill provides concise Rust coding guidelines for the Windmill backend and is required when writing or modifying Rust code in the backend/ directory. It codifies patterns for data modeling, error handling, async usage, SQLx, and module structure to keep code safe, performant, and maintainable. Follow these rules to ensure compatibility with running workers and to avoid common runtime and concurrency mistakes.
How this skill works
The skill inspects code changes conceptually and guides authors to use domain-appropriate types (enums, newtypes), organizes impl blocks, and prefers iterator chains over imperative loops. It enforces safe error handling with the windmill_common::error types, SQLx best practices (no SELECT *), and async patterns that avoid blocking the Tokio runtime. It also recommends mutex choices, serde optimizations, and minimal public surface area.
When to use it
- When creating or modifying structs, enums, or public APIs in backend/.
- When writing database access code with sqlx or designing SQL queries.
- When implementing async logic, threading, or shared state.
- When adding serialization/deserialization for HTTP or DB payloads.
- When organizing impl blocks, modules, or trait implementations.
Best practices
- Model invariants with types (NonZeroU32, Duration, enums) and avoid boolean flags for state.
- Place impl blocks directly under their type and group constructors, getters, mutations, domain logic.
- Prefer iterator chains (.filter().map().collect()) and variable shadowing to keep code concise.
- Return Result<T, Error> using windmill_common::error and use ?/if let/let...else for clear flow.
- Never block the async runtime; use tokio::task::spawn_blocking and bounded channels for backpressure.
- List SQL columns explicitly, batch queries to avoid N+1, and use transactions for multi-step ops.
Example use cases
- Designing a JobState enum to replace multiple boolean flags and encode transitions.
- Implementing a DB read that returns Result<T, Error> and maps sqlx optional rows to NotFound.
- Refactoring a loop into an iterator chain for filtering and transforming items.
- Choosing std::sync::Mutex with Arc for shared in-memory caches and tokio::sync::Mutex only across await points.
- Storing JSONB columns using Box<serde_json::value::RawValue> when no inspection is needed.
FAQ
Use tokio::sync::Mutex only when you must hold the lock across .await points for IO resources; prefer std::sync::Mutex (or parking_lot) for protecting in-memory data to avoid async mutex overhead.
Why avoid SELECT * in sqlx queries?
Explicit columns ensure backward compatibility when the DB schema evolves and avoid surprising runtime mismatches between worker and API versions.