ホームページ > ウェブフロントエンド > jsチュートリアル > ブログ API 統合の最適化: Dev.to と Hashnode から学んだ教訓

ブログ API 統合の最適化: Dev.to と Hashnode から学んだ教訓

DDD
リリース: 2024-12-18 10:53:11
オリジナル
321 人が閲覧しました

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

Astro で個人のポートフォリオを開発しているときに、興味深い課題に遭遇しました。それは、投稿するたびにサイトを再構築せずに、Dev.to と Hashnode の投稿を効率的に統合する方法です。新しいコンテンツ?

問題

問題は最初は単純に見えました。両方のプラットフォームからのすべての投稿を 1 つのページに表示するというものです。ただし、いくつかの課題に直面しました。

  1. ページネーションの制限: 当初は、最初の 20 ~ 30 件の投稿のみを取得していました
  2. 失われた投稿: 新しい投稿を公開するたびに、それが表示されるようにコードを変更する必要がありました
  3. 積極的なキャッシュ: キャッシュが原因で新しい投稿がすぐに表示されませんでした

解決策

1. サーバーレスエンドポイント

両方のプラットフォームからの投稿を結合するサーバーレス エンドポイントを Astro で作成しました。

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. 投稿収益の最大化

重要なのは、可能な最大数の投稿をリクエストすることです:

// 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. キャッシュの回避

コンテンツを新鮮に保つために、アンチキャッシュ戦略を実装しました。

const timestamp = new Date().getTime();
const response = await fetch(`/api/posts.json?_=${timestamp}`, {
  headers: {
    'Cache-Control': 'no-cache',
    'Pragma': 'no-cache'
  }
});
ログイン後にコピー

4. クライアントの実装

インターフェイスを最新の状態に保つために、投稿の読み込みと更新を処理する React コンポーネントを作成しました。

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>
  );
}
ログイン後にコピー

得られるメリット

  1. 自動更新: サイトを再構築しなくても新しい投稿が表示されます
  2. パフォーマンスの向上: サーバーレス エンドポイントのおかげで初期読み込みが速くなります
  3. コンテンツの損失なし: いつ公開されたかに関係なく、すべての投稿にアクセスできます
  4. メンテナンスの軽減: 新しい投稿を表示するために手動介入は必要ありません

エラー処理

堅牢なエラー処理システムを実装しました:

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) : [];
  }
}
ログイン後にコピー

パフォーマンスの最適化

パフォーマンスをさらに向上させるために、以下を実装しました。

  1. ローカルキャッシュ:
// 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. 画像の遅延読み込み:
function PostImage({ src, alt }) {
  return (
    <img 
      loading="lazy"
      src={src} 
      alt={alt}
      className="w-full h-48 object-cover"
    />
  );
}
ログイン後にコピー

このソリューションは堅牢かつ効率的であることが証明されており、次のことが可能になります。

  • ポートフォリオを自動的に更新し続ける
  • 急速充電によるユーザー エクスペリエンスの向上
  • 手動メンテナンスの必要性を軽減
  • すべてのコンテンツが利用可能であり、最新であることを確認してください

次のステップ

次のことを実装する予定です:

  1. 投稿検索およびフィルタリング システム
  2. コンテンツのプレビュー
  3. エンゲージメント指標
  4. 統合コメントシステム

以上がブログ API 統合の最適化: Dev.to と Hashnode から学んだ教訓の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート