Home > Web Front-end > JS Tutorial > Optimizing Blog API Integration: Lessons Learned with Dev.to and Hashnode

Optimizing Blog API Integration: Lessons Learned with Dev.to and Hashnode

DDD
Release: 2024-12-18 10:53:11
Original
319 people have browsed it

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

During the development of my personal portfolio with Astro, I ran into an interesting challenge: how to efficiently integrate my Dev.to and Hashnode posts without having to rebuild the site every time I post new content?

The Problem

The problem seemed simple at first: display all my posts from both platforms on a single page. However, I encountered several challenges:

  1. Pagination Limits: Initially, I was getting only the first 20-30 posts
  2. Lost Posts: Every time I published a new post, I had to modify the code for it to appear
  3. Aggressive Cache: New posts did not appear immediately due to cache

The Solution

1. Serverless Endpoint

I created a serverless endpoint in Astro that combines the posts from both platforms:

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'
    }
  });
};
Copy after login

2. Maximizing Post Earnings

The key is to request the maximum number of posts 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
          }
        }
      }
    }
  }
`;
Copy after login

3. Avoiding the Cache

To ensure fresh content, I implemented an anti-cache strategy:

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

4. Client Implementation

To keep the interface up to date, I created a React component that handles loading and updating posts:

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>
  );
}
Copy after login

Benefits Obtained

  1. Automatic Update: New posts appear without needing to rebuild the site
  2. Better Performance: Initial loading is faster thanks to the serverless endpoint
  3. No Content Loss: All posts are accessible, regardless of when they were published
  4. Reduced Maintenance: No manual intervention required to display new posts

Error Handling

I implemented a robust error handling system:

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) : [];
  }
}
Copy after login

Performance Optimization

To further improve performance, I implemented:

  1. Local Cache:
// 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));
}
Copy after login
  1. Lazy Loading of Images:
function PostImage({ src, alt }) {
  return (
    <img 
      loading="lazy"
      src={src} 
      alt={alt}
      className="w-full h-48 object-cover"
    />
  );
}
Copy after login

This solution has proven to be robust and efficient, allowing me to:

  • Keep my portfolio automatically updated
  • Improve user experience with fast charging
  • Reduce the need for manual maintenance
  • Ensure all my content is available and up to date

Next Steps

I plan to implement:

  1. Post search and filtering system
  2. Content preview
  3. Engagement metrics
  4. Unified comment system

The above is the detailed content of Optimizing Blog API Integration: Lessons Learned with Dev.to and Hashnode. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template