greenhat-services/magpie-laravel
A Laravel package that brings Magpie into your PHP application with a clean service provider, publishable configuration, and familiar Laravel conventions. It keeps integration light, so you can configure the service and start using it quickly in any Laravel project.
This is a pre-1.0 (0.1.x) Laravel package that talks HTTP through Guzzle, so treat it as an early-stage integration rather than a stable dependency. v0.1.1 is a compatibility-only release: it widens the Guzzle constraint from a 7.x-only pin to ^7.8.2|^8.0. No public API, config keys, or behaviour changed, so there is nothing to migrate.
Minimal steps:
composer require <vendor>/<package> and confirm which Guzzle line Composer actually resolves:
composer show guzzlehttp/guzzle
composer why guzzlehttp/guzzle
The constraint is now permissive, but your lock file decides which major you get. On a fresh install you will likely land on Guzzle 8; in an existing app pinned to 7.x you will stay on 7.x. Both are supported and CI-tested at the endpoints (7.8.2 and 8.0).php artisan vendor:publish --provider="...ServiceProvider"), then look at the service provider's bindings before writing your own wrapper — most of these packages bind a single client into the container and expect you to resolve it, not instantiate it.Http::fake() (or the package's own fake) in a test. If the second call doesn't work, you've found the main integration risk early.Where to look first, in order: the service provider (what's bound, singleton or not), the config file (base URL, timeout, retry, auth), the client/transport class (where Guzzle's Client is constructed), then the exception classes.
Pin your Guzzle major deliberately, not accidentally. Because the package now accepts both majors, your application's composer.json is the only thing holding the line. If you have custom Guzzle middleware, handler stacks, or a HandlerStack you assemble yourself, add an explicit constraint ("guzzlehttp/guzzle": "^7.8.2") so a routine composer update in a sibling package can't silently move you to 8. If you have no custom transport code, let it float.
Wrap the package client in your own thin service. Pre-1.0 packages rename methods between patch releases. Put one class between your app and the package:
final class BillingGateway
{
public function __construct(private readonly PackageClient $client) {}
public function charge(ChargeData $data): ChargeResult
{
return ChargeResult::fromResponse($this->client->post('/charges', $data->toArray()));
}
}
Now a package upgrade touches one file, and your domain code speaks your language.
Test at the seam, not the transport. Fake at the level the package exposes (usually Laravel's Http::fake() if it goes through the framework client, otherwise the package's own fake or a mocked PSR-18 client). Assert on the request the package builds — URL path, headers, auth — because that's the contract most likely to shift.
Add a --prefer-lowest CI job. The package's own CI now tests both ends of the Guzzle range; mirror that cheaply in your app so you catch the day a transitive guzzlehttp/psr7 or guzzlehttp/promises bump breaks the low end:
- run: composer update --prefer-lowest --prefer-stable
- run: php artisan test
Bind timeouts and retries in config, not code. Set a sane connect/read timeout and a bounded retry (2–3, with backoff) at the container/config level. With a permissive Guzzle constraint you may run against different default handler behaviour across majors; explicit timeouts make that invisible.
Keep the client resolution inside the request/job lifecycle. Resolve from the container per job rather than storing a client on a long-lived singleton — it keeps config and credentials refreshable and avoids stale connections in Octane/queue workers.
^7.8.2|^8.0 means "installable", not "identical behaviour". Guzzle majors have historically shifted defaults and removed deprecated options; anything you pass through as raw Guzzle options (streams, sink, cookies, proxy, on_headers, custom handlers) is where a major-version difference will bite. Audit any array of raw options you forward.composer require fails, it's almost always the transitive PSR trio (psr7, promises, psr-http-client) or a framework constraint, not the top-level Guzzle line. Run composer why-not guzzlehttp/guzzle 8.0.0 to get the actual blocker instead of guessing.--prefer-lowest job will fail for a reason that has nothing to do with this package.Illuminate\Http\Client is in play, an app-level Guzzle major bump can affect every outbound call in the app, not just this package's. Bump Guzzle in isolation and run the full test suite before merging.0.2.0 may break you. Use "vendor/package": "~0.1.1" (or an exact pin) plus a changelog check on upgrade, and read the diff — patch releases in this range are as likely to be dependency housekeeping as fixes.Http::fake() + Http::recorded() in tests to see the exact request. When a call fails only in one environment, compare the resolved Guzzle version first — composer show guzzlehttp/guzzle in that environment, not locally.composer update guzzlehttp/guzzle -W, execute the app's integration tests against a real sandbox endpoint once, and confirm no custom handler/middleware code assumed 7.x internals. That's the whole migration.How can I help you explore Laravel packages today?