haihai Blog

Next.js のクライアントコンポーネントから外部の REST API を定期的に実行する

2024-07-22

はじめに

Next.js のクライアントコンポーネントから外部の REST API を定期的に実行します。
今回は bitFlyer の public API を利用してビットコインの価格を取得します。
Bun を利用します。

> bun -v
1.1.20

プロジェクト作成

bun create next-app でプロジェクトを作成します。プロジェクト名 btc-ticker 以外はデフォルトを選択しました。

bun create next-app
 What is your project named? btc-ticker
 Would you like to use TypeScript? No / Yes
 Would you like to use ESLint? No / Yes
 Would you like to use Tailwind CSS? No / Yes
 Would you like to use `src/` directory? No / Yes
 Would you like to use App Router? (recommended) … No / Yes
 Would you like to customize the default import alias (@/*)? … No / Yes

動作を確認します。

cd btc-ticker
bun run dev

http://localhost:3000/ へアクセスします。
動作確認ができたら、 Ctrl + c で開発サーバーを停止します。

パッケージインストール

パッケージインストールします。Rest API へのアクセスは swr を利用します。

bun add swr

rewrites へ外部の REST API エンドポイントを設定する

外部の REST API に直接アクセスすると CORS エラーが発生します。 rewrites を Config へ定義し、内部のパスに対するアクセスを外部の REST API のエンドポイントへ書き換えます。 /next.config.mjs へ URL を設定します。

/** @type {import('next').NextConfig} */
const nextConfig = {
  async rewrites() {
    return [
      {
        source: '/bitflyer/btc',
        destination: 'https://api.bitflyer.com/v1/ticker'
      }
    ]
  }
}

export default nextConfig

コード

bitFlyer の Rest API を実行して結果を表示するクライアントコンポーネントを作成します。 /app/components/BfTicker.tsx を追加します。

'use client'

import useSWR from 'swr'

const fetcher = (url: string) => fetch(url).then(res => res.json())
const refreshInterval = 1000

export default function BfTicker() {
  const { data, error, isLoading } = useSWR('/bitflyer/btc', fetcher, {
    refreshInterval: refreshInterval
  })
  console.log('getBfTicker')
  // console.log(data)
  if (error) return 'An error has occurred.'
  if (isLoading) return 'Loading...'

  return (
    <div>
      Bitflyer: {data.ltp}, timestamp: {data.timestamp}
    </div>
  )
}

/app/page.tsx から、クライアントコンポーネントを呼び出すよう修正します。

import BfTicker from './components/BfTicker'

export default function Home() {
  return (
    <main>
      <h1 className='text-3xl'>Bitcoin Ticker</h1>
      <BfTicker />
    </main>
  )
}

解説

  • 'use client' でクライアントコンポーネントであることを宣言します
  • import useSWR from 'swr'SWR ライブラリを読み込みます。
  • const fetcher = (url: string) => fetch(url).then(res => res.json()) は、 指定された url からデータを取得し、 JSON 形式で返却します。
  • const refreshInterval = 1000 でデータの再取得間隔をミリ秒単位で指定します。この場合、1,000 ミリ秒 (1 秒) ごとにデータを再取得します。
  • データ取得
    • useSWR を使って /bitflyer/btc エンドポイントからデータを取得します。
    • fetcher 関数がデータ取得を担当し、refreshInterval オプションでデータの再取得間隔を設定します。
  • 状態管理
    • data: 取得したデータ
    • error: データ取得中にエラーが発生した場合のエラー情報
    • isLoading: データがまだ読み込まれていない場合に true になります
  • {data.ltp}, {data.timestamp} で取得したデータにアクセスします。

動作確認

動作を確認します。

bun run dev

http://localhost:3000/ へアクセスします。1 秒ごとにデータが再取得されていることが確認できます。
また、ブラウザの開発者ツールでコンソールヵらログが確認できます。

画像

参考 URL