confish
Official Rust SDK for confish — typed configuration, actions, and webhook verification.
- Async-first, built on
tokio+reqwest - Typed configuration via the standard
serde::Deserializegeneric —client.fetch::<MyConfig>().await? - Long-running action consumer with
CancellationTokenand bounded concurrency - HMAC-SHA256 webhook verification
Install
[]
= "0.1"
By default the SDK uses rustls. For native TLS, opt in:
= { = "0.1", = false, = ["native-tls"] }
Requires Rust 1.75+.
Quick start
use Client;
use Deserialize;
async
Reading and writing config
// GET /c/{env_id}
let config: MyConfig = client.fetch.await?;
// PATCH — only listed fields change
let updated: MyConfig = client.update.await?;
// PUT — replaces everything; omitted fields reset to defaults
let new_config: MyConfig = client.replace.await?;
Write access must be enabled in environment settings before
updateandreplacewill work.
Logging
use LogLevel;
use json;
client.logger.info.await?;
client.logger.error.await?;
// Or directly:
let log_id = client.log.await?;
Levels: Debug, Info, Notice, Warning, Error, Critical, Alert.
Actions
The action consumer polls for pending actions, acknowledges them, runs your handler, and reports completion or failure — including idempotent skip if another consumer claimed the action first.
use ;
use json;
use Duration;
use CancellationToken;
let cancel = new;
let cancel_clone = cancel.clone;
spawn;
client
.actions
.consume
.await?;
What happens automatically:
- Returning
Ok(Some(value))completes the action withvalueasresult. - Returning
Ok(None)completes with no result. - Returning
Err(_)fails the action with{"error": <message>}. - A
409 Conflicton ack is silently skipped — safe to run multiple consumers. - Cancelling the token halts new work and waits for in-flight handlers to finalize.
- After 3 consecutive empty polls the loop doubles its sleep up to
max_poll_interval, resetting topoll_intervalthe moment any action is processed. Idle consumers make ~240 requests/hour by default.
You can also drive the lifecycle manually:
let actions = client.actions.list.await?;
client.actions.ack.await?;
client.actions.update.await?;
client.actions.complete.await?;
client.actions.fail.await?;
To extract typed params:
if let Some = action.params.clone
Webhook verification
use ;
async
verify uses constant-time comparison and rejects timestamps older than 5 minutes by default. Pass VerifyOptions { tolerance: Duration::ZERO, .. } to disable. Always pass the raw, unparsed body — re-serializing parsed JSON breaks verification.
Errors
use Error;
match client..await
Error::is_conflict() is a convenience for action consumers.
By default the client retries 429 (honoring Retry-After) and 5xx responses up to twice. Tune via the builder.
Builder options
let client = builder
.base_url // override for self-hosted
.user_agent
.max_retries
.max_retry_delay
.http_client // inject your own
.build?;
License
MIT