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 Api Bundle Laravel Package

mmoreram/spotify-api-bundle

Symfony bundle that integrates the Spotify Web API into your app, wrapping the PHP client with service configuration, dependency injection, and ready-to-use endpoints for auth, playlists, tracks, and user data. Lightweight and easy to wire into existing Symfony projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Before you install, know what you're getting. This bundle targets Symfony 2.x and was last released in mid-2014. It is a thin wrapper around the Spotify Web API (metadata: albums, artists, tracks, playlists, search) — it is not the playback SDK, and it has no OAuth flow built in. Zero dependents and 12 stars means you are effectively adopting unmaintained code. Use it if you're already on a legacy Symfony 2 app; otherwise read the "Gotchas" section first and consider a modern client instead.

Minimal setup on a Symfony 2 app:

composer require mmoreram/spotify-api-bundle
// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Mmoreram\SpotifyApiBundle\MmoreramSpotifyApiBundle(),
    );
}

Where to look first:

  1. src/Mmoreram/SpotifyApiBundle/Services/ — the client class. This is the package; read it top to bottom before writing any code. It's a few hundred lines at most.
  2. Resources/config/services.yml — the service id (something like mmoreram.spotify_api). Confirm with:
    php app/console container:debug | grep -i spotify
    
  3. DependencyInjection/Configuration.php — the small set of config keys (base URL, timeouts, any credentials).

First use case — fetch an album and render its tracks, which exercises the whole happy path (HTTP call → response mapping → your template):

// Acme/DemoBundle/Controller/AlbumController.php
public function showAction($spotifyId)
{
    $album = $this->get('spotify_api')->getAlbum($spotifyId);

    return $this->render('AcmeDemoBundle:Album:show.html.twig', array(
        'album' => $album,
    ));
}

If that call returns an array/stdClass with name, artists, and tracks, the bundle is wired correctly and you can build outward from there.

Implementation Patterns

Inject, don't fetch. The service is defined in the container, so wire it into your own classes via constructor or setter injection. Reaching into $this->get('spotify_api') from a service is the fastest route to an untestable codebase.

# Acme/DemoBundle/Resources/config/services.yml
services:
    acme.spotify.repository:
        class: Acme\DemoBundle\Spotify\SpotifyRepository
        arguments: ['@spotify_api']

Wrap it in your own adapter. Given the package's age, treat it as a disposable transport. Define a small interface in your domain (AlbumProviderInterface::find($id)), implement it with a SpotifyApi-backed class, and never let SpotifyApi types leak into controllers or templates. When Spotify's response shape changes — or you swap to jwilsson/spotify-web-api-php — you change one class.

Use it for search and lookups, not for user data. The bundle's surface is essentially read-only metadata (getAlbum, getArtist, getTrack, search...). The natural day-to-day workflows are:

  • Autocomplete / typeahead: call search from a JSON endpoint, throttle the input on the client side, and cache results per normalized query string.
  • Import / sync job: a console command that pages through albums or playlists and persists rows locally, so the front end never talks to Spotify at request time.
  • Twig helper: a Twig extension that turns a stored Spotify ID into a display card, with a local cache in front of it.

Cache aggressively at the adapter layer. Spotify metadata is stable for hours, and you will hit rate limits quickly on a busy site. Use Symfony's doctrine_cache or a simple stash/Redis layer keyed by method + arguments:

$key = 'spotify.album.' . $id;

if (false === $album = $this->cache->fetch($key)) {
    $album = $this->api->getAlbum($id);
    $this->cache->save($key, $album, 3600);
}

Handle errors by translation, not propagation. Guzzle will throw on 4xx/5xx. Catch at the adapter boundary and return null for not-found, re-throw for transport failures, and retry on 429 after honoring Retry-After.

try {
    return $this->api->getTrack($id);
} catch (\Guzzle\Http\Exception\ClientErrorResponseException $e) {
    return null; // 404, or a malformed id
}

Pagination is manual. Spotify uses limit/offset and returns next/previous URLs. The bundle predates any convenience wrapper, so your sync command must loop on offset until the result set is empty. Cap limit at 50.

Testing. Because the service is small, mock it. In a Symfony 2 functional test, replace the spotify_api service in the test container with a stub; in unit tests, mock your own adapter interface and never touch HTTP. Add a thin integration test (marked as slow) that hits /v1/albums/... with a known ID so you notice the day Spotify breaks the bundle's response mapping.

Debug the transport, not the wrapper. If a call fails, temporarily bind a logging listener to the underlying Guzzle client (or just var_dump the raw response body) before blaming the bundle — the wrapper adds very little, so almost every bug is an HTTP/auth problem.

Gotchas and Tips

  • It will not install cleanly on modern Symfony. This is a Symfony 2 bundle: no Flex recipe, no autowiring, and AppKernel registration is required. On Symfony 4+ the bundle class registration still works via config/bundles.php in some cases, but the dependency constraints (PHP 5.x-era Guzzle, old symfony/* ranges) will fight Composer. Expect to fork it, or copy the single service class into your app and drop the bundle scaffolding entirely — honestly, that's often the fastest path.
  • Spotify's API has moved since 2014. The biggest breakage is authentication: the bundle predates the widespread requirement for bearer tokens. You'll likely need to layer on a Client Credentials token (POST to https://accounts.spotify.com/api/token with grant_type=client_credentials) and inject Authorization: Bearer ... into every request — either by subclassing the service or by configuring the underlying Guzzle client's default headers.
  • Hardcoded endpoints and response assumptions are the other time bomb. Spotify has changed field names and removed endpoints over the years; if getAlbum returns unexpected keys, log the raw JSON and patch the mapping locally rather than waiting for an upstream fix that will never come.
  • No token refresh, no retry, no rate-limit handling ships with the bundle. Build these into your adapter once; don't scatter them across controllers.
  • Pin your Guzzle version. Old bundles frequently assume Guzzle 3 (Guzzle\Http\Client, Guzzle\Http\Exception\... namespaces), while most of your other dependencies assume Guzzle 6/7 (GuzzleHttp\Client). Mixing them produces confusing "class not found" errors that look like bundle bugs but are version conflicts. composer why guzzle/guzzle is your friend.
  • Find the real service id before guessing. container:debug beats reading docs that don't exist. The id, the class name, and the config keys are all visible there.
  • Configuration quirks: the config tree is minimal and defaults are baked into the YAML. If you need a custom base URL (for a proxy or a test double), check whether it's actually exposed in Configuration.php; if not, override the service definition in your app's services.yml rather than editing vendor code.
  • Extension points are limited to (a) overriding the service definition with your own class, (b) decorating the service, or (c) subclassing. Prefer (a)/(b) — they survive composer update; vendor edits do not.
  • Don't put Spotify credentials in the bundle config and commit them. Use parameters.yml / environment variables and pass them into your token provider.
  • Treat "unmaintained" as a standing risk item. Add a note to your README or an ADR: this package is frozen at 2014; any Spotify API change is our problem. If the app's lifespan exceeds a year, budget a migration to a maintained client — the adapter boundary described above is exactly what makes that migration a one-file change.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource