How plugins work
Plugins are dynamic libraries (.so on Linux, .dylib on macOS) that implement the Plugin trait. The plugin manager loads these libraries at runtime and executes their hooks during the request/response lifecycle.
Each plugin can implement two hooks:
on_request- Called before a request is processedon_response- Called after a response is generated
Creating a plugin
[package]
name = "logger_plugin"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
async-trait = "0.1"
log = "0.4"
http = "1"
apicentric = { path = "path/to/apicentric" }
use async_trait::async_trait;
use http::{Request, Response};
use log::info;
use apicentric::domain::ports::plugin::Plugin;
struct LoggerPlugin;
#[async_trait]
impl Plugin for LoggerPlugin {
async fn on_request(&self, request: &mut Request<Vec<u8>>) {
info!("-> {} {}", request.method(), request.uri());
}
async fn on_response(&self, response: &mut Response<Vec<u8>>) {
info!("<- {}", response.status());
}
}
#[no_mangle]
#[allow(improper_ctypes_definitions)]
pub extern "C" fn create_plugin() -> Box<dyn Plugin> {
Box::new(LoggerPlugin)
}
Building your plugin
Build the plugin as a dynamic library:target/release/ with a platform-specific name:
- Linux:
liblibname.so - macOS:
liblibname.dylib
Loading plugins
Plugins are loaded from a directory using thePluginManager:
- Scan the directory for dynamic libraries
- Load each library and look for the
create_pluginsymbol - Call
create_plugin()to instantiate the plugin - Register the plugin for request/response hooks
Using plugins
Once loaded, plugins automatically intercept all HTTP traffic:Plugin capabilities
Plugins can modify requests and responses in various ways:Error handling
The plugin manager provides detailed error messages:Ensure each plugin exports a
create_plugin symbol and is built for the current platform. Mixed architectures (e.g., x86_64 plugin on ARM) will fail to load.Best practices
- Keep plugins lightweight - Plugins are called for every request/response
- Handle errors gracefully - Don’t panic in plugin code
- Use structured logging - The example uses the
logcrate for debugging - Test thoroughly - Plugin bugs can affect all traffic
- Version compatibility - Rebuild plugins when upgrading Apicentric
Example use cases
- Authentication - Validate tokens and add user context to requests
- Rate limiting - Track request counts and reject excessive traffic
- Logging - Record detailed request/response information
- Transformation - Convert between data formats
- Caching - Store and retrieve responses based on request patterns
- Monitoring - Collect metrics and send to observability platforms