Next.js の Fetch を利用してコンテンツ一覧を取得する

公開日 :

Next.js には fetch の機能を利用して、外部のデータを取得して処理をするための仕組みが含まれています。今回はこれを利用して、Blog のタイトルを取得したいと思います。

API を作成する

プロジェクトで汎用的に利用できる API として利用できるように GraphQL のクエリの値を取得したらデータを返す、という関数を作成します。実際に作成したコードは以下の URL をクリックすることで、GitHub 上で全コードを見ることができます。

動作としては以下のような記述をしています。

  • fetchGraphQL には query を文字列として渡す

    • apiKey および endpointUrl の値は .env のファイルから読み込んでいます

  • fetch 関数を利用して、上記で指定した endpointUrl に対して、apiKey を利用してクエリを Post します。

  • 正しく json のデータを取得できたとき、json のデータを返しています。

これで GraphQL のクエリを利用して fetchGraphQL を利用して Json のデータを取得できるようになります。

なお、fetch を利用している際に以下のような呼び出しをしています。

    return await fetch(endpointUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-GQL-Token": apiKey,
      },
      body: JSON.stringify({ query }),
      next: { revalidate: 60 },
    })

GraphQL のエンドポイントに対して最後に next: { revalidate: 60 } の記述があります。クエリを実行する際に 60 秒ごとに更新されて、キャッシュされています。

Query を定義する

作成をした fetchGraphQL に渡す Query の定義を追加します。今回は、interfaces/blog/index.ts のファイルに以下のコードを追加しました。前回作成をした AllBlog のクエリを利用しながら、並び順をブログの新着順にして AllBlogQuery として定義しています。

export const AllBlogQuery = `query AllBlog {
  allBlog (orderBy: [PUBLISHDATE_DESC]) {
    total
    results {
      description
      id
      name
      publishDate
      title
      blogImage {
        total
        results {
          id
          name
          description
          fileHeight
          fileId
          fileName
          fileSize
          fileType
          fileUrl
          fileWidth
        }
      }
    }
  }
}
`;

page.tsx の変更

準備が整いました。Next.js のトップページとなる app/page.tsx をガラリと変更して以下のように更新しています。

import { fetchGraphQL } from "@/api";
import { Blog, AllBlogResponse, AllBlogQuery } from "@/interfaces/blog";

export default async function Home() {
  const results: AllBlogResponse = (await fetchGraphQL(
    AllBlogQuery
  )) as AllBlogResponse;

  const posts: Partial<Blog>[] = [];

  results.data.allBlog.results.forEach((post: Partial<Blog>) => {
    posts.push({
      id: post.id,
      description: post.description,
      name: post.name,
      title: post.title,
      publishDate: post.publishDate,
      blogImage: post.blogImage,
    });
  });

  return (
    <main>
      <h1>Content Hub ONE - Title list</h1>
      <ul>
        {posts.map((post) => (
          <>
            <li key={post.id}>{post.title}</li>
          </>
        ))}
      </ul>
    </main>
  );
}

コードを上から紹介していくと、

  • import で事前に作成したコードの読み込み

  • データを Query を利用して AllBlogResponse として取得

  • AllBlogResponse のデータを posts という Blog の配列に変換

  • posts にあるタイトルのみを抜き出して並べる

というごく簡単なコードとなっています。結果は以下の通りです。

random desc

まとめ

実際に Next.js のトップページを変更する形で、コンテンツの一覧を表示することができました。トップページでタイトルを表示しているのみではありますが、データをとって表示ができれば、最初の一歩という形になります。