Implement shared MusicBrainz client crate #14

Closed
opened 2026-03-17 16:33:03 -04:00 by connor · 0 comments
Owner

Both shanty-tag (Issue #4) and shanty-search (Issue #8) need to communicate with the MusicBrainz API. Rather than duplicating the client, rate-limiting logic, and type definitions, extract a shared MusicBrainz client.

This could be a standalone crate (e.g., shanty-mb) or a module within shanty-db. It should provide:

  1. HTTP client — configured with:

    • Proper User-Agent header (Shanty/<version> (<contact>)) as required by MusicBrainz
    • Rate limiting (max 1 request/second for unauthenticated use)
    • Retry logic with exponential backoff for transient failures
    • Timeout configuration
  2. API methods:

    • search_artists(query, limit) → artist results
    • search_releases(query, artist_hint, limit) → release results
    • search_recordings(query, artist_hint, limit) → recording results
    • get_artist(mbid) → full artist details
    • get_release(mbid) → full release details with track listing
    • get_recording(mbid) → full recording details
    • get_artist_releases(mbid) → artist's discography
    • get_cover_art(release_mbid) → cover art URL from Cover Art Archive
  3. Response types — well-typed Rust structs for all API responses, with serde deserialization

  4. Testing — mock server tests (using mockito or wiremock) to test client behavior without hitting the real API

Acceptance Criteria

  • Shared MusicBrainz client crate exists and is usable by shanty-tag and shanty-search
  • Rate limiting enforces max 1 req/sec
  • All listed API methods are implemented
  • Response types are well-defined and deserializable
  • User-Agent header is set correctly
  • Retry logic handles transient failures
  • Tests exist using a mock HTTP server
  • The client is configurable (timeout, rate limit, base URL for testing)

Dependencies

  • Issue #1 (workspace scaffolding)
Both `shanty-tag` (Issue #4) and `shanty-search` (Issue #8) need to communicate with the MusicBrainz API. Rather than duplicating the client, rate-limiting logic, and type definitions, extract a shared MusicBrainz client. This could be a standalone crate (e.g., `shanty-mb`) or a module within `shanty-db`. It should provide: 1. **HTTP client** — configured with: - Proper User-Agent header (`Shanty/<version> (<contact>)`) as required by MusicBrainz - Rate limiting (max 1 request/second for unauthenticated use) - Retry logic with exponential backoff for transient failures - Timeout configuration 2. **API methods:** - `search_artists(query, limit)` → artist results - `search_releases(query, artist_hint, limit)` → release results - `search_recordings(query, artist_hint, limit)` → recording results - `get_artist(mbid)` → full artist details - `get_release(mbid)` → full release details with track listing - `get_recording(mbid)` → full recording details - `get_artist_releases(mbid)` → artist's discography - `get_cover_art(release_mbid)` → cover art URL from Cover Art Archive 3. **Response types** — well-typed Rust structs for all API responses, with `serde` deserialization 4. **Testing** — mock server tests (using `mockito` or `wiremock`) to test client behavior without hitting the real API ### Acceptance Criteria - [ ] Shared MusicBrainz client crate exists and is usable by `shanty-tag` and `shanty-search` - [ ] Rate limiting enforces max 1 req/sec - [ ] All listed API methods are implemented - [ ] Response types are well-defined and deserializable - [ ] User-Agent header is set correctly - [ ] Retry logic handles transient failures - [ ] Tests exist using a mock HTTP server - [ ] The client is configurable (timeout, rate limit, base URL for testing) ### Dependencies - Issue #1 (workspace scaffolding)
connor added the MediumPriority label 2026-03-19 12:27:48 -04:00
connor started working 2026-03-20 13:44:09 -04:00
connor worked for 1 hour 8 minutes 2026-03-20 14:52:42 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Total Time Spent: 1 hour 8 minutes
connor
1 hour 8 minutes
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Shanty/Main#14