Cómo Consumir APIs en Astro: Una Guía Completa imagen

Cómo Consumir APIs en Astro: Una Guía Completa

Astro ofrece múltiples formas de consumir APIs, ya sea desde el servidor durante la construcción del sitio o en el cliente. En esta guía, exploraremos las mejores prácticas y patrones para trabajar con APIs en Astro.

Consumo de APIs en el Servidor

La forma más común y recomendada de consumir APIs en Astro es durante la construcción del sitio, aprovechando el renderizado en el servidor.

Método 1: Usando Top-Level Await

---
// src/pages/posts.astro
const response = await fetch('https://api.ejemplo.com/posts');
const posts = await response.json();
---

<h1>Posts</h1>
<ul>
  {posts.map((post) => (
    <li>
      <h2>{post.title}</h2>
      <p>{post.content}</p>
    </li>
  ))}
</ul>

Método 2: Usando getStaticPaths para Rutas Dinámicas

---
// src/pages/posts/[id].astro
export async function getStaticPaths() {
  const response = await fetch('https://api.ejemplo.com/posts');
  const posts = await response.json();
  
  return posts.map(post => ({
    params: { id: post.id },
    props: { post }
  }));
}

const { post } = Astro.props;
---

<article>
  <h1>{post.title}</h1>
  <p>{post.content}</p>
</article>

Consumo de APIs en el Cliente

Para datos que necesitan actualizarse en tiempo real o después de la interacción del usuario, puedes consumir APIs desde el cliente.

Método 3: Usando Componentes de React

// src/components/DatosDinamicos.jsx
import { useState, useEffect } from 'react';

export default function DatosDinamicos() {
  const [datos, setDatos] = useState([]);
  const [cargando, setCargando] = useState(true);

  useEffect(() => {
    const obtenerDatos = async () => {
      try {
        const respuesta = await fetch('https://api.ejemplo.com/datos');
        const datos = await respuesta.json();
        setDatos(datos);
      } catch (error) {
        console.error('Error al obtener datos:', error);
      } finally {
        setCargando(false);
      }
    };

    obtenerDatos();
  }, []);

  if (cargando) return <div>Cargando...</div>;

  return (
    <ul>
      {datos.map(item => (
        <li key={item.id}>{item.nombre}</li>
      ))}
    </ul>
  );
}

Método 4: Endpoints de API en Astro

// src/pages/api/datos.json.ts
export async function get() {
  try {
    const respuesta = await fetch('https://api.externa.com/datos');
    const datos = await respuesta.json();

    return new Response(JSON.stringify(datos), {
      status: 200,
      headers: {
        'Content-Type': 'application/json'
      }
    });
  } catch (error) {
    return new Response(JSON.stringify({
      error: 'Error al obtener datos'
    }), {
      status: 500,
      headers: {
        'Content-Type': 'application/json'
      }
    });
  }
}

Manejo de Errores y Estados de Carga

Es importante manejar adecuadamente los estados de carga y errores al consumir APIs:

---
// src/pages/datos-protegidos.astro
let datos = [];
let error = null;

try {
  const respuesta = await fetch('https://api.ejemplo.com/datos-protegidos', {
    headers: {
      'Authorization': `Bearer ${import.meta.env.API_KEY}`
    }
  });
  
  if (!respuesta.ok) {
    throw new Error(`Error HTTP: ${respuesta.status}`);
  }
  
  datos = await respuesta.json();
} catch (e) {
  error = e.message;
}
---

<div>
  {error ? (
    <p class="error">Error: {error}</p>
  ) : (
    <ul>
      {datos.map(item => <li>{item.nombre}</li>)}
    </ul>
  )}
</div>

Variables de Entorno

Para manejar claves de API y URLs de forma segura, usa variables de entorno:

# .env
API_KEY=tu_clave_secreta
API_URL=https://api.ejemplo.com
---
// Accede a las variables de entorno
const apiKey = import.meta.env.API_KEY;
const apiUrl = import.meta.env.API_URL;
---

Mejores Prácticas

  1. Caché: Utiliza el caché para datos que no cambian frecuentemente:
const CACHE_DURATION = 3600; // 1 hora en segundos

async function obtenerDatosConCache(url) {
  const cacheKey = `data_${url}`;
  const cachedData = sessionStorage.getItem(cacheKey);
  
  if (cachedData) {
    const { data, timestamp } = JSON.parse(cachedData);
    if (Date.now() - timestamp < CACHE_DURATION * 1000) {
      return data;
    }
  }
  
  const response = await fetch(url);
  const data = await response.json();
  
  sessionStorage.setItem(cacheKey, JSON.stringify({
    data,
    timestamp: Date.now()
  }));
  
  return data;
}
  1. Typing: Si usas TypeScript, define interfaces para tus datos:
interface Post {
  id: number;
  title: string;
  content: string;
  author: string;
  publishDate: string;
}

async function obtenerPosts(): Promise<Post[]> {
  const response = await fetch('https://api.ejemplo.com/posts');
  return response.json();
}

Conclusión

Astro proporciona una gran flexibilidad para consumir APIs tanto en el servidor como en el cliente. La elección del método dependerá de tus necesidades específicas, como la frecuencia de actualización de los datos y los requisitos de SEO.

Recuerda siempre manejar adecuadamente los errores, implementar estados de carga y seguir las mejores prácticas de seguridad al trabajar con APIs en tu aplicación Astro.