perf: stop recommendations from making N+1 API calls

This commit is contained in:
2026-04-08 17:22:07 +02:00
parent 22955c0018
commit 9072348159

View File

@@ -24,12 +24,12 @@ type RecommendationsResponse struct {
Data []RecommendationEntry `json:"data"` Data []RecommendationEntry `json:"data"`
} }
// GetRecommendations fetches full details for the top recommended anime // GetRecommendations fetches recommended anime
func (c *Client) GetRecommendations(animeID int, limit int) ([]Anime, error) { func (c *Client) GetRecommendations(animeID int, limit int) ([]Anime, error) {
cacheKey := fmt.Sprintf("recs:%d", animeID) cacheKey := fmt.Sprintf("recs:%d", animeID)
var cached []Anime var cached []Anime
if c.getCache(cacheKey, &cached) { if c.getCache(cacheKey, &cached) {
if len(cached) > limit { if limit > 0 && len(cached) > limit {
return cached[:limit], nil return cached[:limit], nil
} }
return cached, nil return cached, nil
@@ -49,31 +49,30 @@ func (c *Client) GetRecommendations(animeID int, limit int) ([]Anime, error) {
animes := make([]Anime, 0, max) animes := make([]Anime, 0, max)
for i := 0; i < max; i++ { for i := 0; i < max; i++ {
rec := result.Data[i] rec := result.Data[i]
// Fetch full details so we get English/Japanese titles
fullAnime, err := c.GetAnimeByID(rec.Entry.MalID) // Map the recommendation data directly into an Anime struct.
if err == nil { // By doing this locally, we avoid N additional rate-limited API calls
animes = append(animes, fullAnime) // which was destroying the Jikan limit buckets.
} else { anime := Anime{
// Fallback to partial data if full fetch fails MalID: rec.Entry.MalID,
animes = append(animes, Anime{ Title: rec.Entry.Title,
MalID: rec.Entry.MalID, Images: struct {
Title: rec.Entry.Title, Jpg struct {
Images: struct { LargeImageURL string `json:"large_image_url"`
Jpg struct { } `json:"jpg"`
LargeImageURL string `json:"large_image_url"` Webp struct {
} `json:"jpg"` LargeImageURL string `json:"large_image_url"`
Webp struct { } `json:"webp"`
LargeImageURL string `json:"large_image_url"` }{
} `json:"webp"` Webp: struct {
LargeImageURL string `json:"large_image_url"`
}{ }{
Webp: struct { LargeImageURL: rec.Entry.Images.Webp.LargeImageURL,
LargeImageURL string `json:"large_image_url"`
}{
LargeImageURL: rec.Entry.Images.Webp.LargeImageURL,
},
}, },
}) },
} }
animes = append(animes, anime)
} }
c.setCache(cacheKey, animes, time.Hour*24) c.setCache(cacheKey, animes, time.Hour*24)