lde/api-helper
A Laravel/PHP helper package that streamlines API development with reusable utilities for consistent JSON responses, error handling, and request/response conveniences, helping you build cleaner, more maintainable APIs faster.
The package shipped 8.0.0 — a major version bump — but the release notes are empty. Treat that as the headline: something changed, and nobody wrote down what. Budget the first 30 minutes reading src/ and the git diff between the previous tag and 8.0.0 rather than looking for documentation, which still does not exist.
Install and orient
composer require lde/api-helper
Then, in order:
composer show lde/api-helper --all # list available versions
Compare the tag you're coming from against 8.0.0 on the repo — git log --oneline <old>..8.0.0, git diff <old>..8.0.0 --stat, then read the changed files. A major bump means the public surface moved, so this is not optional.composer.json in the package — re-check extra.laravel.providers/aliases (the FQCN may have changed, which silently breaks your vendor:publish --provider commands) and the illuminate/* constraints. A jump to 8.0.0 often accompanies a Laravel support-version jump. Confirm it resolves against your Laravel before anything else.config/ — if a config is publishable, re-publish it. Config keys are the most common breaking change in a major release, and stale published config is a silent failure mode.src/ — re-identify the public entry points: client/facade, request builder, response or parser class. Note whether HTTP still goes through Guzzle directly or now uses Laravel's Http facade — this decides how you test and mock, and it may well have changed.tests/ — if the release added or rewrote tests, they're your only usage documentation. Read the fixtures.First use case
Start with the narrowest possible thing: one unauthenticated GET returning JSON, mapped into an array or DTO. Call it from php artisan tinker, log the raw response, confirm the parser does what you expect. Only then add auth headers and move to the XML path — the actual reason to reach for this over plain Http::get().
If that takes more than an hour, stop and reassess. An empty changelog on a major release means every upgrade you take from here is an archaeology exercise.
Wrap it, don't sprinkle it. This was true before 8.0.0 and is doubly true after a breaking release. Put the package behind your own interface so no application code imports Lde\ApiHelper\*:
interface ShippingRates
{
public function forPostcode(string $postcode): array;
}
class XmlShippingRates implements ShippingRates
{
public function __construct(private ApiClient $client) {}
public function forPostcode(string $postcode): array
{
$response = $this->client->get('rates', ['postcode' => $postcode]);
return RateMapper::fromXml($response->body());
}
}
Bind it in a service provider. When 9.0.0 arrives with another blank release note, you swap a binding instead of hunting call sites.
Upgrade behind the seam, not across the app. Because the changelog is empty, upgrade in one commit that touches only the wrapper and its tests. If the major bump broke something, the blast radius is one file. Tag the commit with the package version so you can bisect later.
One class per upstream API. Don't build a generic "call anything" wrapper on top of a generic wrapper. Each third-party API gets a small client holding its base URL, auth scheme, and response mapper — that's where the variation lives.
Config over constants. Base URLs, credentials, and timeouts go in config/services.php. If the package publishes config, re-publish after 8.0.0 and diff the old file against the new one before committing — that diff is often the only breaking-change notice you'll get.
XML: map to DTOs at the boundary. Convert to typed objects immediately in the client class. Downstream code should never see SimpleXMLElement. If 8.0.0 changed the parser's return shape, the mapping layer is the only thing you rewrite.
Caching and retries belong outside. Wrap calls in Cache::remember() with a TTL matched to upstream volatility, and add retry logic at your layer unless the package exposes it.
Log raw responses on failure. Log::warning('upstream failed', ['status' => $status, 'body' => $body]) in your client class. With an undocumented major release, your logs are the changelog.
The empty 8.0.0 release note is the risk, not the age. A major version after a long dormancy is genuinely ambiguous: it could be a Laravel 11/12 compatibility refresh, a PHP 8.x bump, a rewrite — or a CI-generated tag with nothing behind it. Read the diff before you assume anything. Pin the exact version ("lde/api-helper": "8.0.0") rather than a caret range, since ^8.0 will absorb 8.0.1 through 8.x with equal silence.
Assume breaking changes until the diff proves otherwise. For a major bump, the highest-probability breakages are: namespace or class renames, the service provider FQCN (breaking vendor:publish --provider), config key renames, changed constructor signatures, and a different HTTP transport. Write the smoke test first, then upgrade.
Re-verify the HTTP transport specifically. If 8.0.0 moved from raw Guzzle to Illuminate\Http\Client, your existing Guzzle mock handlers stop intercepting and Http::fake() starts working — or the reverse, and your suite silently starts hitting the real API in CI. This is still the single most likely thing to bite you, and a major release is exactly when it flips.
XML security, re-checked against the new code. If parsing still goes through simplexml_load_string or DOMDocument::loadXML, confirm flags: pass LIBXML_NONET, avoid LIBXML_NOENT. A rewrite is a chance for a regression here. Cheap to check.
Namespaces and encoding. XML APIs love default namespaces (xmlns="..."), which break naive $xml->foo->bar traversal. Test with a real fixture on day one. Watch for <?xml version="1.0" encoding="ISO-8859-1"?> declarations too.
No community answers means empirical debugging. dd() inside vendor/lde/api-helper/src/ is legitimate and often fastest. Don't burn an hour on Stack Overflow for a package with five stars and no changelog.
Error semantics are probably inconsistent. Decide at your wrapper boundary what a 404 means — empty result or exception. Normalize once, document it.
Timeouts. Set them explicitly in config. A major release can change defaults, and an unset timeout on a synchronous user-facing request is how you get 30-second page loads during an upstream incident.
Extension points to look for after the bump: a publishable config, a container binding for the HTTP client, and any Macroable trait. If 8.0.0 added a binding, use it — that's the one upgrade that would materially improve this assessment.
Have an exit plan. The project is still small and thinly documented, and an undocumented major release is a reminder that you're the maintainer of last resort. If it's behind your own interface from day one, replacing it is an afternoon. If it's called from forty controllers, it isn't.
How can I help you explore Laravel packages today?