# folk-api
Plugin contract crate for the Folk PHP application server. All Folk plugins depend only on this crate.
**Version:** 0.2.0
## Key traits
- **`Executor`** -- dispatches work to PHP workers. Two methods:
- `execute_method(payload: Bytes) -> Result<Bytes>` -- raw bytes dispatch
- `execute_value(value: serde_json::Value) -> Result<serde_json::Value>` -- zero-copy dispatch via `serde_json::Value`, no serialization round-trip. **Preferred path.**
- **`Plugin`** -- lifecycle: `name()`, `boot(ctx)`, `shutdown()`. Optional: `rpc_methods()`.
- **`ServerPlugin`** -- convenience trait for long-lived tasks. Wrap with `ServerPluginWrapper` to get a `Plugin`.
- **`PluginFactory`** -- `create(config: Value) -> Result<Box<dyn Plugin>>`. Called once per plugin crate by the builder.
- **`RpcRegistrar`** -- register admin RPC methods via `register_raw(name, handler)`.
## PluginContext
Every plugin receives a `PluginContext` at boot:
| `executor` | `Arc<dyn Executor>` | Dispatch work to PHP workers |
| `shutdown` | `watch::Receiver<bool>` | Fires on server shutdown |
| `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 is not loaded.
## Plugin lifecycle
1. **Factory** -- `folk_plugin_factory()` returns a `PluginFactory`.
2. **Boot** -- `plugin.boot(ctx)` in registration order. `Err` is fatal.
3. **Run** -- `ServerPlugin::run()` executes as a long-lived task. Watch `ctx.shutdown`.
4. **Shutdown** -- `plugin.shutdown()` in reverse order.
## Installation
```toml
folk-api = "0.2"
```
## Requirements
- Rust 1.88+
## License
MIT