folk-api
Plugin contract for the Folk PHP application server.
Status: in active development. See folk-spec for the roadmap.
Requirements
- Rust 1.85+
- Tokio async runtime
Installation
# Cargo.toml
= "0.1"
Quick start
A minimal plugin that logs on boot and shutdown (~25 lines):
use Result;
use async_trait;
use ;
use Deserialize;
use Value;
;
/// Required entry point — the builder calls this by name.
Register it in folk.build.toml:
[[]]
= "my_greet_plugin"
= "../my-greet-plugin"
= "greet"
And configure it in folk.toml:
[]
= "Howdy"
Configuration
Plugins receive their config section as an opaque serde_json::Value. Each plugin deserializes it into its own struct. There is no global schema — the plugin owns its config shape.
How it works
Plugin lifecycle
- Factory — The builder calls
folk_plugin_factory()once per plugin crate. The returnedPluginFactoryreceives the plugin's config as JSON and constructs aBox<dyn Plugin>. - Boot —
plugin.boot(ctx)is called in registration order at server startup. ReturningErris fatal: already-booted plugins are shut down in reverse order and the server exits. - Run — For
ServerPluginimplementations,run()executes as a long-lived task. Watchctx.shutdownto know when to stop. - Shutdown —
plugin.shutdown()is called in reverse registration order. Errors are logged but do not block the shutdown sequence.
PluginContext
Every plugin receives a PluginContext at boot:
| Field | Type | Description |
|---|---|---|
executor |
Arc<dyn Executor> |
Send work to the PHP worker pool |
shutdown |
watch::Receiver<bool> |
Fires when the server is shutting down |
rpc_registrar |
Option<Arc<dyn RpcRegistrar>> |
Register admin RPC methods |
health_registry |
Option<Arc<dyn HealthRegistry>> |
Register health checks |
metrics_registry |
Option<Arc<dyn MetricsRegistry>> |
Register Prometheus metrics |
Optional registries are None when the corresponding plugin (metrics, etc.) is not loaded. Check before use.
Key traits
Plugin— 3 required methods:name(),boot(),shutdown(). Optional:rpc_methods().ServerPlugin— Convenience trait for the common "spawn a task, wait for shutdown" pattern. Wrap withServerPluginWrapperto get aPlugin.PluginFactory— Single methodcreate(config: Value) -> Result<Box<dyn Plugin>>.Executor—async fn execute(&self, payload: Bytes) -> Result<Bytes>. Sends MessagePack-encoded payloads to the PHP worker pool and returns the response.
RPC methods
Advertise methods from rpc_methods() and register handlers via rpc_registrar.register_raw(name, handler). Handlers receive and return Bytes (typically MessagePack-encoded).
Health checks
Register via health_registry.register(name, check_fn). Return HealthStatus::ok() or HealthStatus::degraded(msg).
Metrics
Create metric families via metrics_registry.counter_vec(name, help, &labels), then .with_labels(&values) to get a handle. Supports counters, gauges, and histograms. All metrics render in Prometheus text format.
See ADR 0006 — Plugin API shape for the full design rationale.
License
MIT