WEBページを作る際に外部 API を使いたいことがあります。
Next.js
で 外部API を叩く際にどうするか整理したので覚書き。
アクセスごとに取得したい API
情報の更新が早い、あるいは常に最新の情報が欲しい場合はアクセスごとにAPIアクセスが必要です。レート制限に注意します。
クライアントサイドで叩く
CORS
設定で許可されている場合にはクライアント側で DOM
構築後に API
を叩くということが出来ます。class
なら componentDidMount
でアクセスしたり、フックを使うなら以下のように書けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import React from "react"; const url = "https://api.github.com/repos/zeit/next.js"; const App = () => { const [stars, setStars] = React.useState(0); React.useEffect(() => { fetch(url) .then((r) => r.json()) .then((j) => setStars(j.stargazers_count)); }, []); return <div>{stars}</div>; }; export default App; |
API
部分以外の画面表示が早くなりますが、API
で得たデータから DOM
追加する場合などでクローラーに正しく評価されないかもしれません。
CORS
で許可されない場合も pages/api/
以下に転送 API
を作ることが出来ます。
単純な転送でなくとも複数 API
を統合して加工したりと便利です。
ただテストで使う分にはいいんですが、個人的には AWS API Gateway
などを使って分離したほうがいいような気がする。
サーバーサイドで叩く
いわゆる SSR(サーバーサイドレンダリング)です。
getInitialProps
か getServerSideProps
を使うことになりますが、今は基本的に getServerSideProps
を使うことになると思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
type Props = { stars: number }; const App = ({ stars }: Props) => { return <div>{stars}</div>; }; const url = "https://api.github.com/repos/zeit/next.js"; export async function getServerSideProps() { const json = await fetch(url).then((r) => r.json()); const stars = json.stargazers_count; return { props: { stars, }, }; } export default App; |
アクセスごとにサーバーでAPIを叩き、レンダリングした結果を返します。
サーバーの負荷が気になりますが、クライアントやクローラーから見ると利点が多い方法になります。
ビルド時に API を叩く
いわゆる SSG(スタティックサイトジェネレーション)です。
情報の更新が少ない API の場合はこちらを検討する。
関数名以外は getServerSideProps
と同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
type Props = { stars: number }; const App = ({ stars }: Props) => { return <div>{stars}</div>; }; const url = "https://api.github.com/repos/zeit/next.js"; export async function getStaticProps() { const json = await fetch(url).then((r) => r.json()); const stars = json.stargazers_count; return { props: { stars, }, }; } export default App; |
これはビルド時に実行され静的ファイルとして書き出される。
API によってはこれが最も良いことがあります。自動で定期的にビルドするようにしておくとより有用です。