gtgt/discogs-api-bundle
gtgt/discogs-api-bundle provides a Symfony integration for the Discogs API, offering configurable client services and dependency injection to query releases, artists, labels, and marketplace data from your PHP application.
This package wraps the Discogs API for Laravel, giving you a configured HTTP client, container bindings, and a fluent surface for releases, collection items, and folders. Version 1.1.0 is a minor, additive release: collection items can now carry a Discogs folder id, so an item can be created directly into a named custom folder instead of landing in Uncategorized.
Minimal setup:
composer require <vendor>/<package> then php artisan vendor:publish --tag=<package>-config. Check the published config for the exact environment key names — typically a personal access token plus a user agent string, which Discogs requires and will reject requests without..env (token and a something/1.0 +contact style user agent). Never rely on the package default user agent in production; Discogs rate-limits or blocks generic agents.app(\Discogs\Client::class) (or whatever the root client class is named in the service provider) — inspect the provider's register() to see whether it is a singleton or a fresh instance per resolution.First use case worth wiring up: list the authenticated user's folders, match a folder by name, then add a release to it.
$folders = $client->user()->collection()->folders($username);
$folderId = collect($folders)->firstWhere('name', 'Wantlist Purchases')['id'];
$client->user()->collection()->addItem($username, [
'release_id' => $releaseId,
'folder_id' => $folderId, // new in 1.1.0
]);
Look first at how the package hydrates responses (array vs. DTO) before writing mapping code — that decision shapes everything downstream.
Folder-aware ingestion. The main workflow this release unlocks is routing incoming records to the right folder at creation time rather than adding everything to Uncategorized and moving it afterwards. Discogs does support moving items between folders, but doing it in one call avoids a second request and the intermediate inconsistent state.
Folder id resolution as a value object. Folder ids are per-user, unstable integers. Resolve names to ids once (a cached config map or a small FolderResolver class) and inject that, rather than hardcoding folder_id => 3 in jobs. Cache the folder list for a few minutes; it changes rarely.
Queue the backfill. Any job that adds many collection items should be queued with a per-request delay. Discogs caps authenticated traffic at roughly 60 requests/minute; a tight loop of addItem calls will start returning 429s partway through.
class AddToCollection implements ShouldQueue
{
public function handle(DiscogsClient $client, FolderResolver $folders): void
{
$client->user()->collection()->addItem(
config('services.discogs.username'),
['release_id' => $this->releaseId, 'folder_id' => $folders->id('Purchases')],
);
}
}
Keep folder ids out of persistence. Store a folder key or name in your own database and translate at call time. Persisting raw Discogs folder ids means a user reorganising their collection silently corrupts your app's mapping.
Testing. Use Http::fake() with a captured response fixture for the add-item endpoint and assert the outgoing request body contains folder_id. The package's client almost certainly builds on Laravel's HTTP client, so Http::assertSent() works without extra tooling.
Integration tip. Treat collection-item creation as non-idempotent. If a queued job retries after a timeout, you can end up with the API having accepted the item even though your side saw an error. Write a small "already in collection" check, or accept duplicates and de-duplicate in a nightly reconcile.
folder_id is a creation-time concern. It is not a general-purpose "move this item" switch. Moving an existing collection item between folders is a separate endpoint; check whether the package exposes it before building a UI around it.message-style body on partial failures, and a naive client will hand you an empty array.retry(3, 2000)) and request logging, rather than wrapping every call site.How can I help you explore Laravel packages today?