Maison >interface Web >js tutoriel >Optimisation de l'intégration de l'API de blog : leçons apprises avec Dev.to et Hashnode

Optimisation de l'intégration de l'API de blog : leçons apprises avec Dev.to et Hashnode

DDD
DDDoriginal
2024-12-18 10:53:11321parcourir

Optimizando la Integración de APIs de Blog: Lecciones Aprendidas con Dev.to y Hashnode

Lors du développement de mon portfolio personnel avec Astro, j'ai été confronté à un défi intéressant : comment intégrer efficacement mes publications Dev.to et Hashnode sans avoir à reconstruire le site à chaque fois que je publie nouveau contenu ?

Le problème

Le problème semblait simple au début : afficher tous mes posts des deux plateformes sur une seule page. Cependant, j'ai rencontré plusieurs défis :

  1. Limites de pagination : Au départ, je ne recevais que les 20 à 30 premiers messages
  2. Messages perdus : Chaque fois que je publiais un nouveau message, je devais modifier le code pour qu'il apparaisse
  3. Cache agressif : Les nouveaux messages ne sont pas apparus immédiatement en raison du cache

La solution

1. Point de terminaison sans serveur

J'ai créé un point de terminaison sans serveur dans Astro qui combine les publications des deux plateformes :

export const GET: APIRoute = async () => {
  const [hashnodePosts, devtoPosts] = await Promise.all([
    getHashnodePosts(),
    getDevToPosts()
  ]);

  const allPosts = [...hashnodePosts, ...devtoPosts]
    .sort((a, b) => 
      new Date(b.rawDate).getTime() - new Date(a.rawDate).getTime()
    );

  return new Response(JSON.stringify(allPosts), {
    headers: {
      'Content-Type': 'application/json',
      'Cache-Control': 'no-store, no-cache, must-revalidate'
    }
  });
};

2. Maximiser les revenus postérieurs

La clé est de demander le maximum de publications possible :

// Para Dev.to
const params = new URLSearchParams({
  username: 'goaqidev',
  per_page: '1000', // Máximo número de posts
  state: 'published'
});

// Para Hashnode
const query = `
  query {
    publication(host: "goaqidev.hashnode.dev") {
      posts(first: 1000) { // Máximo número de posts
        edges {
          node {
            title
            brief
            // ...otros campos
          }
        }
      }
    }
  }
`;

3. Éviter le cache

Pour garantir la fraîcheur du contenu, j'ai mis en place une stratégie anti-cache :

const timestamp = new Date().getTime();
const response = await fetch(`/api/posts.json?_=${timestamp}`, {
  headers: {
    'Cache-Control': 'no-cache',
    'Pragma': 'no-cache'
  }
});

4. Implémentation client

Pour garder l'interface à jour, j'ai créé un composant React qui gère le chargement et la mise à jour des publications :

import { useState, useEffect } from 'react';

function BlogPosts() {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const timestamp = new Date().getTime();
        const response = await fetch(`/api/posts.json?_=${timestamp}`);
        const data = await response.json();
        setPosts(data);
      } catch (error) {
        console.error('Error fetching posts:', error);
      } finally {
        setLoading(false);
      }
    };

    fetchPosts();
    // Actualizar cada 5 minutos
    const interval = setInterval(fetchPosts, 5 * 60 * 1000);
    return () => clearInterval(interval);
  }, []);

  if (loading) return <div>Cargando posts...</div>;

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
      {posts.map(post => (
        <article key={post.id} className="card">
          <h2>{post.title}</h2>
          <p>{post.brief}</p>
          <a href={post.url}>Leer más</a>
        </article>
      ))}
    </div>
  );
}

Avantages obtenus

  1. Mise à jour automatique : De nouveaux messages apparaissent sans avoir besoin de reconstruire le site
  2. Meilleures performances : le chargement initial est plus rapide grâce au point de terminaison sans serveur
  3. Aucune perte de contenu : Tous les articles sont accessibles, quelle que soit la date de leur publication
  4. Maintenance réduite : Aucune intervention manuelle requise pour afficher les nouveaux messages

Gestion des erreurs

J'ai implémenté un système de gestion des erreurs robuste :

async function fetchPosts() {
  try {
    const response = await fetch('/api/posts.json');
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const posts = await response.json();
    return posts;
  } catch (error) {
    console.error('Error fetching posts:', error);
    // Intentar cargar desde caché local si está disponible
    const cachedPosts = localStorage.getItem('blog_posts');
    return cachedPosts ? JSON.parse(cachedPosts) : [];
  }
}

Optimisation des performances

Pour améliorer encore les performances, j'ai mis en place :

  1. Cache local :
// Guardar posts en localStorage
localStorage.setItem('blog_posts', JSON.stringify(posts));

// Cargar posts desde localStorage mientras se actualiza
const cachedPosts = localStorage.getItem('blog_posts');
if (cachedPosts) {
  setPosts(JSON.parse(cachedPosts));
}
  1. Chargement paresseux des images :
function PostImage({ src, alt }) {
  return (
    <img 
      loading="lazy"
      src={src} 
      alt={alt}
      className="w-full h-48 object-cover"
    />
  );
}

Cette solution s'est avérée robuste et efficace, me permettant de :

  • Garder mon portfolio automatiquement mis à jour
  • Améliorez l'expérience utilisateur avec une charge rapide
  • Réduisez le besoin de maintenance manuelle
  • Assurer que tout mon contenu est disponible et à jour

Prochaines étapes

Je prévois de mettre en œuvre :

  1. Système de recherche et de filtrage des publications
  2. Aperçu du contenu
  3. Mesures d'engagement
  4. Système de commentaires unifié

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn