37. 3 Api películas.

 

Tutorial 37.3: Consumiendo API de Películas

Introducción a la API de The Movie Database

Ahora vamos a consumir la API de The Movie Database (TMDb), que puedes encontrar en api.themoviedb.org. Esta es una API gratuita que nos proporcionará toda la información sobre películas que necesitamos para nuestra aplicación.

Requisitos para usar la API:

  • Es necesario registrarse para obtener una clave de API (API Key)

  • La API es gratuita con ciertas limitaciones

  • Necesitamos un token de autorización para hacer peticiones

Tipos de endpoints disponibles

La API de TMDb nos ofrece tres formas principales de buscar películas:

1. Discover - Descubrir películas

text

/discover/movie

Muestra películas con filtros opcionales por categorías, recomendado cuando quieres mostrar una lista general de películas.

2. Search - Búsqueda por texto

text

/search/movie

Busca películas específicas por nombre, ideal para implementar un buscador.

3. Find - Buscar por ID

text

/find/{id}

Busca una película específica por su ID único, útil cuando conoces el identificador exacto.

Para nuestro proyecto inicial, vamos a comenzar con Discover para mostrar una lista general de películas.

Configurando nuestro cliente HTTP

Vamos a crear una estructura organizada para manejar nuestras peticiones a la API.

Paso 1: Crear la estructura de carpetas

Primero, creamos una carpeta data dentro de src para organizar nuestro código relacionado con la API:

text

src/

├── data/

│   └── httpClient.js

├── App.jsx

├── App.css

└── ...

Paso 2: Crear el archivo httpClient.js

Dentro de src/data/httpClient.js, vamos a crear nuestro cliente HTTP:

javascript

// Base URL de la API

const API = "https://api.themoviedb.org/3/";


/**

 * Función para realizar peticiones GET a la API de TMDb

 * @param {string} path - Ruta específica del endpoint (ej: 'discover/movie')

 * @returns {Promise} - Promesa con los datos en formato JSON

 */

export function get(path) {

    return fetch(API + path, {

        headers: {

            Authorization: 

                "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI1NzlkN2ZmMzJmMzgxZGQ3YjY3ZWViMWVhOGI4MTY0YSIsInN1YiI6IjVjM2ExNmIwMGMyNzEwMDAxODc1MjgwIiwic2NvcGVzIjpbImFwaV9yZWFkIl0sInZlcnNpb24iOjF9.nOpZ_nBtA93tbzr6-rxD0760tssAAaSppyjRv9anArs",

            "Content-Type": "application/json;charset=utf-8"

        }

    }).then((result) => result.json());

}

Explicación del código:

  1. URL Base: Definimos la URL base de la API (https://api.themoviedb.org/3/)

  2. Función get: Exportamos una función que recibe un path como parámetro

  3. Headers: Incluimos dos headers importantes:

    • Authorization: Con el token Bearer para autenticación

    • Content-Type: Especificamos que trabajamos con JSON

  4. Transformación de respuesta: Convertimos la respuesta a JSON con .then((result) => result.json())

Importante sobre el token:

El token que ves en el código es funcional y puedes usarlo para practicar. Sin embargo, para un proyecto real, deberías:

  1. Registrarte en themoviedb.org

  2. Obtener tu propia API Key

  3. Guardarla de forma segura (no exponerla públicamente)

Probando nuestro cliente HTTP

Paso 3: Modificar App.jsx para consumir la API

Ahora vamos a modificar nuestro componente principal para usar el cliente HTTP:

jsx

import { useEffect, useState } from 'react';

import { get } from './data/httpClient';

import './App.css';


function App() {

    const [movies, setMovies] = useState([]);

    const [loading, setLoading] = useState(true);

    const [error, setError] = useState(null);


    useEffect(() => {

        // Función para obtener las películas

        const fetchMovies = async () => {

            try {

                setLoading(true);

                // Usamos el endpoint 'discover/movie' para obtener películas populares

                const data = await get('discover/movie');

                setMovies(data.results);

            } catch (err) {

                setError('Error al cargar las películas');

                console.error(err);

            } finally {

                setLoading(false);

            }

        };


        fetchMovies();

    }, []);


    if (loading) {

        return (

            <div className="App">

                <header>

                    <h1 className="title">Películas 🎬</h1>

                </header>

                <div className="loading">

                    <p>Cargando películas...</p>

                </div>

            </div>

        );

    }


    if (error) {

        return (

            <div className="App">

                <header>

                    <h1 className="title">Películas 🎬</h1>

                </header>

                <div className="error">

                    <p>{error}</p>

                </div>

            </div>

        );

    }


    return (

        <div className="App">

            <header>

                <h1 className="title">Películas 🎬</h1>

                <p className="subtitle">

                    Mostrando {movies.length} películas

                </p>

            </header>

            

            <main>

                <div className="movies-grid">

                    {movies.slice(0, 12).map((movie) => (

                        <div key={movie.id} className="movie-card">

                            <img

                                src={`https://image.tmdb.org/t/p/w300${movie.poster_path}`}

                                alt={movie.title}

                                className="movie-poster"

                            />

                            <div className="movie-info">

                                <h3>{movie.title}</h3>

                                <p className="movie-rating">

                                    ⭐ {movie.vote_average.toFixed(1)}

                                </p>

                                <p className="movie-release">

                                    {new Date(movie.release_date).getFullYear()}

                                </p>

                            </div>

                        </div>

                    ))}

                </div>

            </main>

        </div>

    );

}


export default App;

Paso 4: Agregar estilos para las películas

Actualiza App.css:

css

/* Estilos existentes... */


/* Contenedor principal */

.App {

    max-width: 1200px;

    margin: 0 auto;

    padding: 0 1rem;

}


/* Subtítulo */

.subtitle {

    text-align: center;

    color: #a0a0a0;

    margin-bottom: 2rem;

}


/* Grid de películas */

.movies-grid {

    display: grid;

    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

    gap: 2rem;

    margin: 2rem 0;

}


/* Tarjeta de película */

.movie-card {

    background: #16213e;

    border-radius: 10px;

    overflow: hidden;

    transition: transform 0.3s ease, box-shadow 0.3s ease;

    cursor: pointer;

}


.movie-card:hover {

    transform: translateY(-5px);

    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);

}


/* Poster de la película */

.movie-poster {

    width: 100%;

    height: 300px;

    object-fit: cover;

}


/* Información de la película */

.movie-info {

    padding: 1rem;

}


.movie-info h3 {

    font-size: 1.1rem;

    margin-bottom: 0.5rem;

    color: #ffffff;

    white-space: nowrap;

    overflow: hidden;

    text-overflow: ellipsis;

}


.movie-rating {

    color: #ffd700;

    font-weight: bold;

    display: flex;

    align-items: center;

    gap: 0.5rem;

}


.movie-release {

    color: #a0a0a0;

    font-size: 0.9rem;

}


/* Estados de carga y error */

.loading, .error {

    text-align: center;

    padding: 4rem;

    font-size: 1.2rem;

}


.loading p {

    color: #ffd700;

}


.error p {

    color: #ff6b6b;

}


/* Responsive */

@media (max-width: 768px) {

    .movies-grid {

        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));

        gap: 1rem;

    }

    

    .title {

        font-size: 2rem;

    }

}

Resultado final

¡Felicidades! Ahora tienes una aplicación de películas que:

  1. ✅ Consume una API real de películas

  2. ✅ Muestra las películas más populares

  3. ✅ Tiene manejo de estados de carga y error

  4. ✅ Diseño responsive y atractivo

  5. ✅ Estructura de código organizada y mantenible

Próximos pasos sugeridos

En los siguientes tutoriales podrías:

  1. Implementar búsqueda - Usar el endpoint search/movie

  2. Agregar paginación - Para mostrar más películas

  3. Crear vista de detalle - Mostrar información completa de cada película

  4. Agregar filtros - Por género, año de lanzamiento, etc.

  5. Implementar favoritos - Guardar películas favoritas en localStorage

Consejo: Explora la documentación de TMDb para descubrir todas las funcionalidades disponibles que puedes implementar en tu aplicación.

¡Excelente trabajo! Tu aplicación ya está consumiendo datos reales y mostrando información actualizada sobre películas. 


Comentarios

Entradas más populares de este blog

11. Creando un proyecto react con create-react-app

29. useEffect

38. 4 Routers