swisnl/json-api-client
A PHP package for Laravel that maps remote JSON:API resources to Eloquent models. Consume JSON:API services with familiar Eloquent syntax, including relationships, filtering, sorting, pagination, and eager loading. It handles response parsing and model hydration, providing a read-only client.
This release (2.6.2) is a compatibility release: it adds Laravel 13 support via #112. There are no API changes, so the day‑to‑day entry point is unchanged — pin the version and confirm your framework constraint.
composer require <vendor>/<package>:^2.6
composer.json platform constraints. If you are on Laravel 13, 2.6.2 is the floor — anything below it will fail resolution or fail at runtime on framework internals. If you are on Laravel 11/12, 2.6.2 is a drop‑in patch upgrade.composer show <vendor>/<package>
php artisan vendor:publish --provider="<Vendor>\<Package>\<Package>ServiceProvider" --tag=config
Read the package's composer.json (require, extra.laravel.providers, extra.laravel.aliases) and its config/ directory. In a package this small, the config file and the service provider are the documentation.php artisan tinker
>>> app(<Vendor>\<Package>\Contracts\...::class);
Where to look first, in order: README → config/*.php → service provider register()/boot() → tests/ (the test suite is the most accurate spec of behavior, and it is also where you'll see what Laravel 13 changed).
Pin the floor, not the ceiling. Use "<vendor>/<package>": "^2.6.2" rather than ^2.6. Minor versions of small packages are frequently compatibility-only, and the floor is the thing that matters.
Keep framework upgrades and package upgrades in one PR. Because 2.6.2 exists specifically to unblock Laravel 13, upgrade both together and let CI prove it. A separate "bump Laravel" PR followed by "bump package" PR hides which side broke.
Matrix your CI. If the package supports a range (e.g. Laravel 11–13), test your app on the framework version you actually deploy on, plus one ahead. Add a Laravel 13 job now so the next compatibility release is a non-event:
strategy:
matrix:
laravel: ["^11.0", "^12.0", "^13.0"]
Wrap it, don't sprinkle it. Bind the package's client/manager into a thin application-level service and inject that. This is the single highest-value pattern for small third-party packages: when the package's API shifts (or you swap it out), you change one class instead of 40 call sites.
// app/Services/Billing.php
public function __construct(private \Vendor\Package\Client $client) {}
Register the binding in a dedicated AppServiceProvider method so it is greppable.
Test against the real container, not mocks. For Laravel-integrated packages, $this->app behavior (config resolution, facades, deferred providers) is where bugs live. Prefer orchestra/testbench-style integration tests in your own suite over mocking the facade.
Use the config file as the extension point. Publish it once, commit it, and drive behavior from config/<package>.php rather than constructor arguments scattered through the codebase. Anything time-sensitive (retries, timeouts, cache TTLs) belongs there and should be read via config() at call time — not cached in a property in register().
php artisan config:cache freezes config(). If the package reads config in a service provider's register(), changing the config file without config:clear looks like the change was ignored. Always php artisan optimize:clear after touching published config in local/staging.php artisan about or composer dump-autoload -v output to confirm the provider is discovered. If the package predates your Laravel version's discovery format, register it manually in bootstrap/providers.php (Laravel 11+) — note the move away from config/app.php providers here.Str/Arr helpers, updated type hints, changed default casts). Run your full suite on Laravel 13 rather than assuming it's inert. Check the diff of #112 if the package is public — it's usually a handful of lines and tells you exactly which framework surfaces it touches.^2.6.2 requirement can conflict with another package still capped at Laravel 12. Diagnose with composer why-not <vendor>/<package> 2.6.2 rather than deleting composer.lock.composer.lock hostage. After upgrading, commit the lock file and run composer validate --strict; the lock diff is your audit trail for what Laravel 13 pulled in transitively.php artisan tinker against the container binding → the package's own tests/ → vendor/<vendor>/<package>/src (read the actual register()/boot(), it's short) → storage/logs/laravel.log with APP_DEBUG=true. Reaching for a debugger before step 3 is usually wasted time on a package this size.How can I help you explore Laravel packages today?