feat: use bulk Spotify API calls & inserts to make spotify crawling more efficient (#271)

* feat(spotify-api): bulk endpoints
* feat(music-library): allow bulk operations
* feat(spotify): bulk track+album+artist+genre import
* feat(spotify): use bulk import api for user crawl
* feat(spotify): bulk listen insert

For the benchmark case of a new user where Listory imports 50 new listens along with all now tracks, artists, albums & genres we significantly reduced the number of things happening:

    Spotify API Requests: 208 => 8
    DB Insert: 96 => 8
    Tracing Spans: 1953 => 66
This commit is contained in:
Julian Tölle 2023-05-07 02:20:43 +02:00 committed by GitHub
parent 24b7308343
commit 8721fd101d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 427 additions and 23 deletions

View file

@ -45,6 +45,22 @@ export class SpotifyApiService {
return artist.data;
}
async getArtists(
accessToken: string,
spotifyIDs: string[]
): Promise<ArtistObject[]> {
const artist = await firstValueFrom(
this.httpService.get<{ artists: ArtistObject[] }>(`v1/artists`, {
headers: { Authorization: `Bearer ${accessToken}` },
params: {
ids: spotifyIDs.join(","),
},
})
);
return artist.data.artists;
}
async getAlbum(accessToken: string, spotifyID: string): Promise<AlbumObject> {
const album = await firstValueFrom(
this.httpService.get<AlbumObject>(`v1/albums/${spotifyID}`, {
@ -54,6 +70,21 @@ export class SpotifyApiService {
return album.data;
}
async getAlbums(
accessToken: string,
spotifyIDs: string[]
): Promise<AlbumObject[]> {
const album = await firstValueFrom(
this.httpService.get<{ albums: AlbumObject[] }>(`v1/albums`, {
headers: { Authorization: `Bearer ${accessToken}` },
params: {
ids: spotifyIDs.join(","),
},
})
);
return album.data.albums;
}
async getTrack(accessToken: string, spotifyID: string): Promise<TrackObject> {
const track = await firstValueFrom(
this.httpService.get<TrackObject>(`v1/tracks/${spotifyID}`, {
@ -63,4 +94,20 @@ export class SpotifyApiService {
return track.data;
}
async getTracks(
accessToken: string,
spotifyIDs: string[]
): Promise<TrackObject[]> {
const track = await firstValueFrom(
this.httpService.get<{ tracks: TrackObject[] }>(`v1/tracks`, {
headers: { Authorization: `Bearer ${accessToken}` },
params: {
ids: spotifyIDs.join(","),
},
})
);
return track.data.tracks;
}
}