smartbox/camel-config-bundle
Smartbox Camel Config Bundle offers Symfony integration for loading and managing Camel configuration in PHP applications, with configuration helpers and service wiring that simplify connecting Camel components to your project.
composer require smartbox/camel-config-bundle:^1.10
The package registers itself through its service provider; if it ships publishable config, publish it once and commit the result:
php artisan vendor:publish --tag=camel-config
If no tag exists, the defaults live in the package's own config/ directory — read that file rather than the README, which on a package with 0 stars and a multi-year gap between releases is frequently stale.
Where to look first: the package's config file and the definitions it points at. As of v1.10.0 there is now a delay interceptor definition, so the fastest way to understand the package's mental model is to find that class — it will show you how an interceptor is declared, what parameters it takes, and how it gets resolved from config into the runtime pipeline. Everything else (ordering, registration, defaults) follows the same shape.
First use case: register the delay interceptor and confirm it actually runs.
// config/camel.php (key names: verify against the package's own config file)
'interceptors' => [
'delay' => [
'enabled' => env('CAMEL_DELAY_ENABLED', false),
// e.g. 'milliseconds' => 250,
],
],
Then resolve the pipeline out of the container and prove the interceptor is present before wiring it into anything real:
php artisan tinker
>>> app(\Smartbox\CamelConfig\Contracts\InterceptorPipeline::class) // adjust to the real binding
If the binding doesn't resolve, the alias in the service provider differs from the package name — check the provider's register()/boot() for the container keys it actually binds.
Treat the delay interceptor as an infrastructure concern, not business logic. It exists to space out work: retry backoff, throttling outbound calls, smoothing bursts against a rate-limited API. Keep the delay value in config and env, never inline in the pipeline definition, so you can zero it out in testing and local without touching code.
Compose, don't fork. The value of an interceptor model is stacking: logging → delay → retry → transport. Register the delay in the middle of the stack via config, and add your own behaviour as a separate interceptor implementing the package's interceptor contract rather than editing the vendored one:
final class LoggingInterceptor implements InterceptorInterface
{
public function handle($payload, Closure $next)
{
Log::debug('camel.interceptor', ['payload' => $payload]);
return $next($payload);
}
}
Bind or tag it the same way the package tags its built-ins (check the provider for the tag name), then it participates in ordering for free.
Environment layering. Laravel's config merge is shallow at the top level but recursive for nested arrays, so per-environment files or .env overrides work — provided you use the same nesting the package expects. A config/camel.php in config/ plus env-driven values is usually enough; avoid array_merge in a provider, it will clobber the package defaults.
Testing pattern. Never let the delay actually sleep in the test suite. Freeze time or disable the interceptor:
protected function setUp(): void
{
parent::setUp();
config(['camel.interceptors.delay.enabled' => false]);
}
Then assert ordering and composition (which interceptors ran, in what order, with what payload) rather than wall-clock timing. If you must assert the delay duration, inject a clock/sleeper abstraction — otherwise the suite becomes slow and flaky.
Adapter for vendor risk. Wrap the pipeline behind your own interface so a future swap is a one-file change:
interface CamelPipelineInterface
{
public function send(Payload $payload): Result;
}
v1.10.0 is additive — a new interceptor definition, no deprecations or breaking changes signalled. Pin to ^1.10 and keep the minor bump; there's no migration work implied. But "new definition" means it may be declared without being enabled — check whether it defaults to on or off before assuming behaviour changed after upgrading.
Units are the classic failure mode. Delay interceptors in the wild are split between milliseconds, microseconds and seconds. A 250 that you assumed was milliseconds and the package treats as seconds will hang a queue worker for four minutes and look exactly like a deadlock. Confirm from the interceptor class, not the release note.
A delay interceptor blocks the process it runs in. Inside a queued job that's fine; inside a web request it's a sleeping PHP-FPM worker. If the interceptor uses sleep()/usleep() you cannot make it non-blocking — so for anything user-facing, move the pipeline into a job and let the delay happen off the request path.
Ordering matters more than the delay itself. Delay placed outside a retry interceptor delays once; placed inside it delays between every attempt. That's the difference between a 250 ms request and a 1 s one. Read the stack in resolved order, not source order.
php artisan config:cache is the #1 "my change isn't applying" cause. Cached config is a plain PHP array; editing config/camel.php or .env changes nothing until you re-run php artisan config:cache (or config:clear in dev). Long-running queue workers also need queue:restart.
Unknown keys are usually silent. If your new interceptor entry has no effect, it's more likely a typo'd key or wrong nesting level than a bug — the package's config merge typically ignores extras. Cross-check against the package's own config file, then dump the resolved array: php artisan tinker → config('camel').
Vendor risk is unchanged and now the main argument for the adapter. 0 stars, 0 dependents, a score around 0.26, and a release cadence measured in years. The delay interceptor is a small amount of logic. If, after reading it, it's a few dozen lines, copy it into app/Camel/Interceptors/DelayInterceptor.php and drop the dependency; if it's genuinely entangled with a pipeline and config-resolution layer, keep the package but put your CamelPipelineInterface in front of it so the swap stays cheap.
Extension points, in order of preference: (1) config overrides, (2) your own interceptor class added to the stack, (3) decorating/re-binding a resolved pipeline in a service provider. Reach for a container extend() or a tag-based compiler step only if the package doesn't expose the pipeline as a resolvable binding — and if it doesn't, that itself is a reason to reconsider adoption.
Write one integration test that resolves the pipeline and asserts the delay interceptor is present and configured. With no dependents to catch regressions upstream, that test is how you'll find out a future minor release silently changed the default or the ordering — before production does.
How can I help you explore Laravel packages today?