Generalize YouTube-backed endpoints behind a source parameter
Removes the last YouTube-specific routes (/youtube/*) and merges them
into the general track/album/playlist endpoints, keyed by a `source`
string validated against TrackSource. This mirrors the earlier track
search merge for albums and playlist-track additions:
- GetAlbums now merges local albums with live YouTube Music search
results, paginated via a youtubeContinuationToken, deduped against
already-materialized ExternalAlbum rows.
- New GET /albums/external/{source}/{externalId} and
GET /tracks/external/{source}/{externalId}/stream replace the
YouTube-only equivalents.
- POST /playlists/{id}/tracks replaces the separate
.../youtube-tracks endpoint, accepting an optional Source/ExternalId
pair alongside TrackId.
- AlbumSearchItemResponse/AlbumsSearchResponse follow the same
discriminated-union + trailing-HasNextPage-field pattern already
used for track search, so HasNextPage stays a required field in the
generated OpenAPI schema.
- Frontend routes renamed accordingly (/albums/youtube/[albumId] ->
/albums/external/[source]/[externalId], etc.) with a single
/api/thumbnail proxy replacing /api/youtube/thumbnail.
Musify.Api.Endpoints.YouTubeEndpoints and the standalone
SearchYouTubeAlbums query are removed as a result.
This commit is contained in:
@@ -7,6 +7,8 @@ using Musify.Application.Albums;
|
||||
using Musify.Application.Albums.Responses;
|
||||
using Musify.Application.Shared;
|
||||
using Musify.Application.Tracks.Responses;
|
||||
using Musify.Application.YouTube;
|
||||
using Musify.Domain.ValueObjects;
|
||||
|
||||
namespace Musify.Api.Endpoints;
|
||||
|
||||
@@ -19,8 +21,8 @@ public static class AlbumEndpoints
|
||||
|
||||
group.MapGet("/", GetAlbums)
|
||||
.WithName("GetAlbums")
|
||||
.WithSummary("Get Paginated Albums.")
|
||||
.Produces<PaginatedResponse<AlbumApplicationResponse>>();
|
||||
.WithSummary("Get Paginated Albums, Combined With Live YouTube Music Results When A Title Filter Is Given.")
|
||||
.Produces<AlbumsSearchResponse>();
|
||||
|
||||
group.MapGet("/{id}", GetAlbumById)
|
||||
.WithName("GetAlbumById")
|
||||
@@ -28,6 +30,12 @@ public static class AlbumEndpoints
|
||||
.Produces<AlbumApplicationResponse>()
|
||||
.Produces(StatusCodes.Status404NotFound);
|
||||
|
||||
group.MapGet("/external/{source}/{externalId}", GetExternalAlbum)
|
||||
.WithName("GetExternalAlbum")
|
||||
.WithSummary("Get An Album From An External Source (Currently Only YouTube Music) With Its Tracklist.")
|
||||
.Produces<YouTubeAlbumDetail>()
|
||||
.Produces(StatusCodes.Status404NotFound);
|
||||
|
||||
group.MapGet("/users/{userId}", GetAlbumsByUserId)
|
||||
.WithName("GetAlbumsByUserId")
|
||||
.WithSummary("Get Paginated Albums For A User.")
|
||||
@@ -100,9 +108,10 @@ public static class AlbumEndpoints
|
||||
CancellationToken cancellationToken,
|
||||
string? title,
|
||||
int pageNumber = 1,
|
||||
int pageSize = 10)
|
||||
int pageSize = 10,
|
||||
string? youtubeContinuationToken = null)
|
||||
{
|
||||
var result = await mediator.Send(new GetAlbumsQuery(title, pageNumber, pageSize), cancellationToken);
|
||||
var result = await mediator.Send(new GetAlbumsQuery(title, pageNumber, pageSize, youtubeContinuationToken), cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
@@ -115,6 +124,19 @@ public static class AlbumEndpoints
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static async Task<IResult> GetExternalAlbum(
|
||||
IMediator mediator,
|
||||
string source,
|
||||
string externalId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!Enum.TryParse<TrackSource>(source, ignoreCase: true, out var trackSource) || trackSource != TrackSource.YouTube)
|
||||
return Results.NotFound($"Unknown or unsupported source '{source}'.");
|
||||
|
||||
var result = await mediator.Send(new GetYouTubeAlbumQuery(externalId), cancellationToken);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static async Task<IResult> GetAlbumsByUserId(
|
||||
IMediator mediator,
|
||||
long userId,
|
||||
|
||||
Reference in New Issue
Block a user