kirsankifat/symfony_api_service
A Symfony package that provides a service-oriented foundation for building API endpoints, helping organize request handling and reusable API logic within Symfony applications. Designed to streamline API development with a simple, structured integration.
Install with composer require <vendor>/<package> and confirm you land on 1.4.2 or later (composer show <vendor>/<package>). If you were already pinned below 1.4.2, read the Gotchas section before running composer update — 1.4.2 changes an interface signature.
Publish what the package ships before writing code: php artisan vendor:publish --provider="<Vendor>\<Package>\<PackageServiceProvider>". Most Laravel packages gate config, migrations, or stubs behind tags; check --tag= options in the package README rather than publishing everything blindly.
Look first at the contract, not the concrete class. The 1.4.2 change ("add parameters into interface") means the package's public interface is the thing your application code couples to. Open the interface file (src/Contracts/*.php) and confirm which parameters are new and whether they carry defaults. That single file tells you whether your existing implementations still compile.
Resolve the binding from the container rather than instantiating classes yourself:
$service = app(\Vendor\Package\Contracts\ThingContract::class);
This is the assumption the whole package is built around; every pattern below depends on it.
First real use case: implement the interface in one small class of your own, bind it in a service provider, and inject it into a controller or job. Once that round-trip works, the rest of the package is variations on it.
Bind the contract, not the class. Register your implementation in a dedicated service provider:
public function register(): void
{
$this->app->bind(
\Vendor\Package\Contracts\ThingContract::class,
\App\Services\MyThing::class,
);
}
Use bind for stateless services and singleton only when the package documentation says the object holds per-request state. Rebinding a singleton after resolution silently does nothing — a frequent source of "my config is ignored" bugs.
Implement the interface with the new parameters accounted for. After 1.4.2 your implementation must match the widened signature. If the added parameters have defaults, your existing implementation is usually fine as long as you don't narrow the signature:
final class MyThing implements ThingContract
{
public function handle(string $input, array $options = [], ?string $context = null): mixed
{
// accept the new args even if you ignore them
}
}
Decorate rather than fork. Wrap the package's default implementation to add logging, caching, or tenancy scoping without editing vendor code:
$this->app->extend(ThingContract::class, function (ThingContract $inner, $app) {
return new CachedThing($inner, $app->make('cache')->store());
});
Keep invocation sites free of positional-argument coupling. The interface now takes more parameters; if callers pass arguments positionally, adding a parameter ahead of an existing one is a silent behaviour change. Prefer named arguments ($service->handle(input: $x, options: [...])) anywhere the package's signature is still moving.
Test against the contract, not the package. Swap in a fake in tests so a minor-version interface change never breaks your suite:
$this->mock(ThingContract::class, function ($mock) {
$mock->shouldReceive('handle')->once()->andReturn($expected);
});
Pin sensibly. For a package that is still evolving its interfaces, "^1.4" is reasonable but "~1.4.0" is safer if you implement its contracts directly. Commit composer.lock and treat interface changes as reviewable events, not background noise.
Fatal error: Declaration of ... must be compatible with .... Grep before you upgrade: grep -rn "implements .*ThingContract" app/ tests/. Then run php -l or, better, PHPStan/Larastan over app/ — the error surfaces at class-load time, so a test that never touches the class will not catch it.1.4.1 and open an issue. If they have defaults, implementors keep working but callers relying on func_get_args(), reflection, or third-party decorators may still break.php artisan config:clear && php artisan cache:clear && composer dump-autoload. Stale config caches and stale autoloaders produce failures that look like interface mismatches but are not.How can I help you explore Laravel packages today?