smartbox/api-bundle
A PHP API bundle for Smartbox applications that streamlines building and exposing API endpoints, with configurable routing, serialization, and response handling for consistent backend integrations.
Reality check first. This is a Symfony bundle from Smartbox Group, not a Laravel package. It has 2 stars, 0 dependents, and before v0.14.0 its last release was January 2023. One minor release does not constitute a maintenance signal — it's still a 0.x version, which by semver means the author reserves the right to break you on any bump. Before you invest a sprint, open composer.json and confirm the Symfony constraint matches your app.
What v0.14.0 tells us the bundle actually does. The release note — "Add new skipSoap option to endpoint definitions to define if the endpoint must be skipped by the soap service loader" — resolves the biggest ambiguity in the previous assessment. This bundle is an endpoint registry: you declare endpoints in bundle config, and one or more "service loaders" consume those definitions to register services. One of those loaders is SOAP-specific. That's the mental model to hold:
config/packages/<alias>.yaml → endpoint definitions → service loaders (incl. soap) → container services
If you're proceeding (legacy Symfony app already using it, or evaluating for interop):
DependencyInjection/Configuration.php first. It is the only authoritative schema. Everything you can write in YAML is in that tree, including the shape of an endpoint definition and where skipSoap sits (per-endpoint, as a boolean).skipSoap in src/ on day one — that single grep shows you the loader class, how it reads the flag, and which other loaders don't respect it. This is the highest-value five minutes you'll spend.composer.json. A pre-1.0 bundle targeting Symfony 5.4/6.x will install into 6.4 but may fight on composer update via transitive constraints.tests/. If the skipSoap flag has a functional test, that test is your usage example. If it doesn't, the flag is unverified — treat it as "probably works for the author's case."config/bundles.php, declare one endpoint under config/packages/, set skipSoap: true on it, and run php bin/console debug:container --show-private | grep -i <alias>. Confirm the SOAP service is absent. That one assertion proves the definition path, the loader, and the flag all line up.The honest recommendation for a Laravel shop: unchanged. Don't adopt this. Endpoint-definition-plus-loader is a Symfony container idiom; Laravel has no equivalent and no config/bundles.php. If you just want SOAP or JSON API plumbing, Laravel gives you Http, Resources, and a far healthier ecosystem (saloonphp/saloon, spatie/laravel-query-builder, league/fractal). Investigate only for interop with a Symfony service that already depends on it.
Endpoint definitions are the interface. Day-to-day, you are not calling bundle PHP classes — you are editing a YAML map of endpoints. Each entry carries attributes (path, handler, auth, and now skipSoap). Structure your config so each endpoint reads as a self-contained record:
# config/packages/smartbox_api.yaml
smartbox_api:
endpoints:
orders_list:
# ...path/handler/whatever the Configuration.php defines
skipSoap: true
orders_create:
skipSoap: false
Use the exact key casing from Configuration.php (skipSoap, not skip_soap — see gotchas).
Use skipSoap as your per-endpoint opt-out. The intended workflow the release enables: the SOAP loader sweeps up every declared endpoint by default, and skipSoap: true removes one from that sweep. Reach for it when:
Wrap the bundle in a gateway. Never let the SOAP client leak across the app. Inject it into one class:
final class OrdersSoapGateway
{
public function __construct(private OrdersServiceInterface $soap) {}
public function list(): array
{
return $this->soap->listOrders();
}
}
When (not if) the bundle stalls, you swap one constructor argument.
Decoration over forking. If the loader gives you an interface, decorate it in config/services.yaml with decorates: to add logging, retries, or metrics without touching vendor code. If it gives you only concrete final classes, you have no seam and should not build on it.
Per-environment endpoints. Because definitions live in YAML, use Symfony's multi-file config (when@dev, or config/packages/dev/) to flip skipSoap per environment. Classic use: skip SOAP in local/dev where the upstream WSDL isn't reachable, keep it enabled in prod.
Regression test as contract. Pin the flag's behavior with a container test, since upstream may not:
public function testSoapClientNotRegisteredForSkippedEndpoint(): void
{
$container = static::getContainer();
$this->assertFalse(
$container->has('smartbox_api.soap.orders_list'),
'skipSoap should suppress the SOAP service'
);
}
Adjust the service ID to whatever debug:container actually reports. This test is worth more than the README, and it will fail loudly if a future version changes the flag's semantics.
skipSoap is scope-limited by name. It says SOAP loader, and it means SOAP loader. If an endpoint is also picked up by an HTTP/REST/other loader, setting skipSoap: true will not remove it from those. Verify per loader with debug:container. If you need "disable this endpoint entirely," this flag is not that knob — check Configuration.php for a broader enabled-style option.- to _ in config keys, but camelCase and snake_case are not interchangeable. Write skipSoap exactly as Configuration.php defines it. Getting this wrong on Symfony 6.1+ fails container build with a "Unrecognized option" error that points at the parent node, not your typo.Configuration.php over any changelog prose.php bin/console cache:clear. If skipSoap "doesn't work," clear cache before you debug the flag.skipSoap: "false" (quoted) is a non-empty string and may coerce truthy depending on how Configuration.php validates. Use bare true / false and let the config tree's booleanNode do its job.^0.14 still permits feature additions and, by convention, behavior changes. Pin exactly (0.14.0) rather than range-constraining, and add composer audit to CI so you learn about transitive breakage on your schedule.php bin/console debug:config <alias> for the resolved config, php bin/console debug:container --show-private | grep -i <alias> for what the loaders actually registered. For the 0.14.0 change specifically, debug:container is the only way to observe the flag's effect.*Interface.php in src/. If the SOAP client and loaders are interfaces, you can decorate, mock, and replace. If they're all final with no interface, skipSoap is your only lever and that's not enough for long-lived code.// TODO: replace smartbox/api-bundle comment linking to this assessment.How can I help you explore Laravel packages today?