Next.js で API リクエストを行う方法 3 つのパターン例をまとめます。
それぞれの方法で、PokeAPI を使ってピカチュウの情報を取得してみます。
サンプルコードはこちらに置いています。
70-10/nextjs-api-request
API にリクエストする 3 つのパターン
- CSR (Client-side Rendering)
- ページのレンダリングをブラウザで行う
- API リクエストはブラウザから行われる
- SSR (Server-side Renderring)
- ページのレンダリングをサーバーで行う
- API リクエストはサーバーから行われる
- SSG (Static-site Generation)
- ページのレンダリングをビルド時に行う
- API リクエストはビルドを実行処理のなかで行われる
実装イメージはこんな感じ。図鑑番号と名前、画像が表示されるというシンプルなもの。
1. CSR (Client-side Rendering)
import type { Pokemon } from "@/models/pokemon";
import Image from "next/image";
import useSWR from "swr";
const pokeapiUrl = "https://pokeapi.co/api/v2/pokemon/25";
const fetcher = (url: string) => fetch(url).then((res) => res.json());
export default function CSR() {
const { data, error, isLoading } = useSWR<Pokemon>(pokeapiUrl, fetcher);
return (
<main>
<h2>CSR (Client-side Rendering)</h2>
{error && <p>Failed to load</p>}
{isLoading && <p>Loading...</p>}
{data && (
<>
<p>
{data.id}: {data.name}
</p>
<Image
src={pokemon.sprites.front_default}
width={200}
height={200}
alt="Picture of the author"
/>
</>
)}
</main>
);
}
2. SSR (Server-side Renderring)
import type { Pokemon } from "@/models/pokemon";
import type { GetServerSideProps, InferGetServerSidePropsType } from "next";
import Image from "next/image";
const pokeapiUrl = "https://pokeapi.co/api/v2/pokemon/25";
interface Props {
pokemon: Pokemon;
}
export default function SSR({
pokemon,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<main>
<h2>SSR (Server-side Rendering)</h2>
<p>
{pokemon.id}: {pokemon.name}
</p>
<Image
src={pokemon.sprites.front_default}
width={200}
height={200}
alt="Picture of the author"
/>
</main>
);
}
export const getServerSideProps: GetServerSideProps<Props> = async (
context,
) => {
const res = await fetch(pokeapiUrl);
const pokemon = (await res.json()) as Pokemon;
return {
props: {
pokemon,
},
};
};
3. SSG (Static-site Generation)
import type { Pokemon } from "@/models/pokemon";
import type { GetStaticProps, InferGetStaticPropsType } from "next";
import Image from "next/image";
const pokeapiUrl = "https://pokeapi.co/api/v2/pokemon/25";
interface Props {
pokemon: Pokemon;
}
export default function SSG({
pokemon,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return (
<main>
<h2>SSG (Static-site Generation)</h2>
<p>
{pokemon.id}: {pokemon.name}
</p>
<Image
src={pokemon.sprites.front_default}
width={200}
height={200}
alt="Picture of the author"
/>
</main>
);
}
export const getStaticProps: GetStaticProps<Props> = async (context) => {
const res = await fetch(pokeapiUrl);
const pokemon = (await res.json()) as Pokemon;
return {
props: {
pokemon,
},
};
};