saloonphp/saloon
Saloon is a PHP package for building beautiful, class-based API integrations. Define connectors and requests, then handle authentication, caching, retries, pagination, and testing through a clean, framework-agnostic API that works with Laravel or any PHP project.
StripeConnector, TwilioRequest). This reduces coupling between business logic and HTTP clients, improving testability and reusability.RetryMiddleware, LoggingMiddleware), allowing cross-cutting concerns (auth, rate limiting) to be defined once and reused across connectors.PaymentIntent::fromResponse($response->json())).ApiRequestSent, ApiResponseReceived) via middleware, enabling observability (e.g., logging, monitoring) without polluting business logic.HasApiVersion trait lets a connector declare its target vendor API version once, at the class level, instead of embedding version strings in every request path/header. This fits Laravel’s config-driven architecture: version becomes an explicit, reviewable property of the connector rather than an implicit detail buried in URLs. It also makes concurrent support of two vendor API versions (e.g., during a Stripe/AWS deprecation window) a first-class pattern — two connectors, one trait, no duplicated request classes.HttpClient facade, Illuminate\Support\Facades\Http). Existing Laravel HTTP logic (e.g., Http::post()) can be gradually migrated to Saloon’s structured approach.AppServiceProvider, with connectors bound as singletons or contextual bindings (e.g., app()->bind(StripeConnector::class, fn() => new StripeConnector(config('stripe')))).use HasApiVersion; plus a $apiVersion property to the base connector is a one-file change. No refactor of existing request classes is required, and no breaking change is introduced by the release. Existing connectors continue to behave exactly as before.Http facade or Guzzle. Mitigation: Pair programming and internal documentation (e.g., "Saloon vs. Guzzle" cheat sheet).stripe/stripe-php), duplication of effort may arise. Mitigation: Benchmark Saloon vs. vendor SDKs for maintainability (e.g., mocking, customization) before adoption.MockPaymentGateway).HasApiVersion makes a vendor version change a one-line edit. That is a benefit for maintenance but a governance risk — a trivial-looking PR can silently change every request a connector makes. Mitigation: version lives in config/env, not hardcoded; version bumps require contract tests against recorded fixtures and a changelog review.^4.5 if the team adopts the trait.Http::get()) or only new integrations?HasApiVersion cover all three, or do we need per-vendor conventions on top of the trait?Http facade, GuzzleHttp, or Symfony HTTP Client.Authenticator classes.ApiRequestFailed) for reactive workflows.config('services.stripe.version')), keeping environment-specific versions out of source control diffs.MockClient enables isolated API testing without external calls.fixtures/stripe/2024-06-01/) so a version bump surfaces missing coverage immediately.config('api.base_url')) work seamlessly with Laravel Sail.new SaloonStripeConnector($guzzleClient)).feature() to toggle between old (Guzzle) and new (Saloon) implementations.V2 connectors alongside V1 using HasApiVersion, flip traffic via config, and retire the old connector after the sunset date.Http Facade: Replace all Http::get() calls with Saloon connectors.App\Middleware\LogRequests) with Saloon-specific middleware.Illuminate\Support\Facades\Http).HasApiVersion requires >= 4.5.0. Pin ^4.5 in composer.json if the trait is adopted; teams on 4.4.x need an explicit minor bump. No transitive dependency changes reported.ApiConnector with shared middleware).HasApiVersion to the base connector and source the version from config; document path vs. header handling per vendor.Http facade) with Saloon.HasApiVersion usage should be captured in the internal "Saloon vs. Guzzle" cheat sheet.HasApiVersion lets one codebase address multiple vendor versions or regional API surfaces without branching request logic, which keeps the operational surface flat as the integration count grows.Authenticator classes with refresh logic and alerting on 401 rate.composer.json, automated dependency updates with CI gates, and a mocked regression suite.$apiVersion in the wrong environment or without fixtures. Mitigation: version sourced from config, environment-scoped, with fixture coverage required for any new version value.How can I help you explore Laravel packages today?