Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Spotify Client Laravel Package

calliostro/spotify-client

A PHP client for the Spotify Web API that simplifies authentication and access to Spotify data. Framework-agnostic and easy to drop into Laravel or any PHP project, it wraps API endpoints in a clean, developer-friendly interface for building music-powered applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This package wraps Guzzle/Laravel HTTP client calls with rate-limit-aware retry handling. The v1.0.1 release is a maintenance/CI release — it does not introduce breaking changes or new runtime features — so the onboarding path is unchanged.

  1. Install and discover the config.

    composer require <vendor>/<package>
    php artisan vendor:publish --tag=<package>-config
    

    The published config is the first file to read: it exposes max_retries, backoff, and rate-limit knobs. Check composer.json requirements for the supported matrix (PHP 8.1–8.6, Guzzle 7 or Guzzle 8), which matches what CI now explicitly tests.

  2. Register the middleware. Attach the package middleware to the Guzzle handler stack, or to a named Laravel HTTP client. Confirm the middleware is ordered after logging/history middleware so retries are visible in your HTTP logs.

  3. First use case. Point it at a single flaky third-party API: set max_retries to a small number, enable rate limiting, and issue a request through the instrumented client. Watch for the expected Retry-After/backoff behaviour before rolling it out across all clients.

Implementation Patterns

  • Per-client configuration over global defaults. Create one Laravel HTTP client macro per upstream service (Http::withOptions(...)) and set retry/rate-limit values on that client. Different upstreams have very different tolerances, and a single global max_retries will either be too aggressive or too timid.
  • Zero-retry escape hatch. A max_retries of 0 is a legitimate configuration for non-idempotent endpoints. v1.0.1 adds a unit test covering exactly this case, so you can rely on it as a documented “fail fast” mode rather than a loophole.
  • Backoff with jitter for concurrency. When many jobs hit the same rate-limited API, deterministic backoff causes thundering herds. Prefer the package’s jittered/exponential strategy and keep max_retries low (2–3) unless the endpoint is known-safe.
  • Pair with Laravel queues. For batch jobs, combine the package’s rate limiter with RateLimited/redis queue middleware so retries happen at the HTTP layer and at the job layer without duplicating effort. Ensure the job’s own retry count accounts for the HTTP retries it will consume.
  • Test with Http::fake + sequence. Assert both the happy path and the retry path:
    Http::fake([
        'api.example.com/*' => Http::sequence()
            ->push(['error' => 'rate limited'], 429, ['Retry-After' => '1'])
            ->push(['ok' => true], 200),
    ]);
    
    Then assert the number of recorded requests and that the final response succeeded.
  • Guzzle 7 vs Guzzle 8. Since both are now explicitly tested, pick the one your other dependencies pin and don’t mix them across packages. Middleware APIs are largely compatible but handler-stack construction details differ; if your app also ships custom Guzzle middleware, verify ordering under the version you actually install.
  • Observability. Log retry attempts with attempt number, status code, and delay. This is the fastest way to spot a misconfigured upstream and to justify raising or lowering max_retries.

Gotchas and Tips

  • max_retries = 0 is not “unlimited”. It disables retries. The new test in v1.0.1 formalises this behaviour; don’t assume 0 or null means “retry forever”.
  • Rate limiting and retries are separate concerns. The limiter paces requests; the retry policy reacts to failures. Configuring one and expecting the other to compensate is the most common source of “why is this still 429-ing?” confusion.
  • Middleware order matters. Putting the retry middleware before authentication/signing middleware means each retry re-signs (usually fine) or re-reads a consumed body stream (usually not fine). For requests with non-rewindable bodies, ensure retries happen before the body is exhausted, or buffer the payload.
  • Idempotency. Retrying POST/PATCH without an idempotency key can duplicate side effects. Use max_retries = 0 for non-idempotent calls, or restrict retries to connection errors/5xx where the server almost certainly did not process the request.
  • Retry-After handling. Honour server-provided delays where present, but cap them — a misbehaving upstream can return an absurd value and stall workers. Check whether your config exposes a maximum delay; if not, wrap or subclass the backoff strategy.
  • Debugging. Temporarily lower max_retries to 1 and enable Guzzle’s debug option to see the raw exchange. If retries “don’t happen”, confirm the exception/status is in the package’s retryable set — a 4xx other than 429 is typically excluded by design.
  • PHP version drift. CI covers PHP 8.1 through 8.6; if your app is still on 8.1, keep it in the matrix of your own test suite before bumping dependencies, since transitive Guzzle upgrades can shift behaviour.
  • Extension points. The backoff strategy and the retryable-exception predicate are the two seams worth customising. Prefer extending these over forking the middleware, so future patch releases (like this one) apply cleanly.
  • Upgrading to v1.0.1. No action required for application code — the release only touches CI workflows, the compatibility matrix, docs, and composer.json metadata. Re-run your test suite if you rely on Guzzle 8, since it is now a first-class supported target rather than an untested combination.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle