simon-schubert/terry-api
Terry API is a Laravel package that streamlines building RESTful APIs. It offers a structured foundation for defining endpoints, handling requests, and returning consistent JSON responses, helping you ship API features with less boilerplate and greater consistency.
composer require <vendor>/<package>:^0.8.1. The only change in v0.8.1 is that psr/log now accepts ^1 || ^2 || ^3 (previously narrower), so this release is what makes the package installable alongside newer Laravel/Monolog stacks. If you were pinned to an older tag because of a psr/log conflict, this is the version to move to.LoggerInterface binding, channel mapping, and processor registration will live. Run php artisan vendor:publish --provider="...ServiceProvider" if a config file is offered, and read the binding before reading the internals.composer show psr/log and composer why psr/log. On Laravel 9+ you will typically resolve psr/log 3.x via Monolog 3; on older stacks you may still be on 1.x/2.x. Both are now legal for this package, but they are not the same interface (see Gotchas).Psr\Log\LoggerInterface into a controller or queued job, log a message with a context array, and confirm it lands in storage/logs/laravel.log and honours LOG_CHANNEL. That single test proves the binding, the channel routing, and the PSR-3 bridge all work on your stack.Log:: at the application edges (middleware, console commands, service providers) and inject LoggerInterface into services, actions, and jobs. This is the main day-to-day payoff: your code stays framework-agnostic and testable, and the package's binding decides where records actually go.payments, sync, audit) rather than one global logger. Route by binding a contextualised logger per service, or by resolving Log::channel('payments') and passing it in as the LoggerInterface.['order_id' => $id, 'attempt' => $n] as the context array; reserve the message for the human-readable event name. This is what makes the output searchable and what survives a swap of the underlying handler.pushProcessor / a withContext-style API), register it once there instead of threading the ID through every call site.handle() and pop/reset in a finally, or scope the contextual logger to the job only.LoggerInterface to a spy or Psr\Log\NullLogger in the test container. Assert on the records (level, message, context keys) rather than on log file contents — that is the whole reason to type-hint the interface.composer update <vendor>/<package> psr/log --with-dependencies so the lockfile actually re-resolves; a plain composer update may leave you on the old PSR-3 pin and hide the benefit.LoggerInterface rather than just consuming it, the signatures differ: 2.x added void return types and typed array $context; 3.x widened $message to string|\Stringable. An implementation written against ^1 will fatal or fail an interface check once Composer resolves 2/3. Widening the constraint only helps if the implementation was already updated.psr/log to ^1. Diagnose with composer why-not psr/log ^3 before assuming the package is at fault.Stringable in messages only works on PSR-3 3.x. If you rely on passing objects with __toString as $message, it will be rejected or mishandled on a 1.x/2.x resolution. Cast explicitly to (string) if you need to support both.php artisan config:cache (and config:clear while debugging) — a stale cached config is the most common "my new channel doesn't log" cause.report()/catch logging will duplicate records. Pick one owner per failure path.LoggerInterface, any channel-resolver or processor hook in the config, and the published config file itself. Rebinding the interface in a test or a tenancy package is the cleanest way to redirect output without touching call sites.How can I help you explore Laravel packages today?