161 lines
4.7 KiB
Go
161 lines
4.7 KiB
Go
// Package tmdb provides a client for The Movie Database (TMDB) API.
|
|
//
|
|
// This package offers a clean interface for interacting with TMDB's REST API,
|
|
// including automatic rate limiting, retry logic, and convenient URL building utilities.
|
|
//
|
|
// # Getting Started
|
|
//
|
|
// First, create an API connection using your TMDB API token:
|
|
//
|
|
// api, err := tmdb.NewAPIConnection()
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
//
|
|
// The token is read from the TMDB_TOKEN environment variable.
|
|
//
|
|
// # Making Requests
|
|
//
|
|
// The package provides clean URL building functions to construct API requests:
|
|
//
|
|
// // Simple endpoint
|
|
// url := tmdb.requestURL("movie", "550")
|
|
// // Result: "https://api.themoviedb.org/3/movie/550"
|
|
//
|
|
// // With query parameters
|
|
// url := tmdb.buildURL([]string{"search", "movie"}, map[string]string{
|
|
// "query": "Inception",
|
|
// "page": "1",
|
|
// })
|
|
// // Result: "https://api.themoviedb.org/3/search/movie?language=en-US&page=1&query=Inception"
|
|
//
|
|
// All requests made with buildURL automatically include "language=en-US" by default.
|
|
//
|
|
// # Rate Limiting
|
|
//
|
|
// TMDB has rate limits around 40 requests per second. This package implements
|
|
// automatic retry logic with exponential backoff:
|
|
//
|
|
// - Initial backoff: 1 second
|
|
// - Exponential growth: 1s → 2s → 4s → 8s → 16s → 32s (max)
|
|
// - Maximum retries: 3 attempts
|
|
// - Respects Retry-After header when provided by the API
|
|
//
|
|
// Example of rate-limited request:
|
|
//
|
|
// data, err := api.get(url)
|
|
// if err != nil {
|
|
// // Will return error only after exhausting all retries
|
|
// log.Printf("Request failed: %v", err)
|
|
// }
|
|
//
|
|
// # Searching for Movies
|
|
//
|
|
// Search for movies by title:
|
|
//
|
|
// results, err := tmdb.SearchMovies(token, "Fight Club", false, 1)
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
//
|
|
// for _, movie := range results.Results {
|
|
// fmt.Printf("%s %s\n", movie.Title, movie.ReleaseYear())
|
|
// fmt.Printf("Poster: %s\n", movie.GetPoster(&api.Image, "w500"))
|
|
// }
|
|
//
|
|
// # Getting Movie Details
|
|
//
|
|
// Fetch detailed information about a specific movie:
|
|
//
|
|
// movie, err := tmdb.GetMovie(550, token)
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
//
|
|
// fmt.Printf("Title: %s\n", movie.Title)
|
|
// fmt.Printf("Overview: %s\n", movie.Overview)
|
|
// fmt.Printf("Release Date: %s\n", movie.ReleaseDate)
|
|
// fmt.Printf("IMDb ID: %s\n", movie.IMDbID)
|
|
//
|
|
// # Getting Credits
|
|
//
|
|
// Retrieve cast and crew information:
|
|
//
|
|
// credits, err := tmdb.GetCredits(550, token)
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
//
|
|
// fmt.Println("Cast:")
|
|
// for _, actor := range credits.Cast {
|
|
// fmt.Printf(" %s as %s\n", actor.Name, actor.Character)
|
|
// }
|
|
//
|
|
// fmt.Println("\nCrew:")
|
|
// for _, member := range credits.Crew {
|
|
// if member.Job == "Director" {
|
|
// fmt.Printf(" Director: %s\n", member.Name)
|
|
// }
|
|
// }
|
|
//
|
|
// # Image URLs
|
|
//
|
|
// The API configuration includes base URLs for images. Use helper methods to
|
|
// construct full image URLs:
|
|
//
|
|
// posterURL := movie.GetPoster(&api.Image, "w500")
|
|
// // Available sizes: "w92", "w154", "w185", "w342", "w500", "w780", "original"
|
|
//
|
|
// # Error Handling
|
|
//
|
|
// The package returns wrapped errors for easy debugging:
|
|
//
|
|
// data, err := api.get(url)
|
|
// if err != nil {
|
|
// if strings.Contains(err.Error(), "rate limit exceeded") {
|
|
// // Handle rate limiting
|
|
// } else if strings.Contains(err.Error(), "unexpected status code") {
|
|
// // Handle HTTP errors
|
|
// } else {
|
|
// // Handle network errors
|
|
// }
|
|
// }
|
|
//
|
|
// Common error scenarios:
|
|
// - "rate limit exceeded: maximum retries reached" - All retry attempts exhausted
|
|
// - "unexpected status code: 401" - Invalid API token
|
|
// - "unexpected status code: 404" - Resource not found
|
|
// - Network errors for connectivity issues
|
|
//
|
|
// # Environment Variables
|
|
//
|
|
// The package uses the following environment variable:
|
|
//
|
|
// - TMDB_TOKEN: Your TMDB API access token (required)
|
|
//
|
|
// Obtain an API token from: https://www.themoviedb.org/settings/api
|
|
//
|
|
// # Best Practices
|
|
//
|
|
// 1. Reuse the API connection instead of creating new ones for each request
|
|
// 2. Use buildURL for consistency and automatic language parameter injection
|
|
// 3. Handle rate limit errors gracefully - they indicate temporary service issues
|
|
// 4. Cache API responses when appropriate to reduce API calls
|
|
// 5. Use specific image sizes instead of "original" to save bandwidth
|
|
//
|
|
// # API Documentation
|
|
//
|
|
// For complete TMDB API documentation, visit:
|
|
// https://developer.themoviedb.org/docs
|
|
//
|
|
// # Rate Limiting Details
|
|
//
|
|
// From TMDB's documentation:
|
|
// "While our legacy rate limits have been disabled for some time, we do still
|
|
// have some upper limits to help mitigate needlessly high bulk scraping. They
|
|
// sit somewhere in the 40 requests per second range."
|
|
//
|
|
// This package automatically handles rate limiting with exponential backoff to
|
|
// ensure respectful API usage.
|
|
package tmdb
|