API Routesで設定するAPIにSWRでPOSTする(+ useRouterの使用)
Next.jsではAPI Routesを利用して簡単にAPIエンドポイントが設定できます。
今回はAPI Routesで設定するエンドポイントにuseSWR
を使ってPOST
してみます。
- パッケージ
"next": "12.3.1", "swr": "^1.3.0",
静的なページからPOSTする
/api/post
に投稿する静的なページpost.js
を作成します。
- src/pages/post.js
import useSWR from 'swr' const Page = () => { const post = { method: 'POST', headers: { 'Content-Type': 'application/json'}, body: JSON.stringify('postページからの投稿'), } const fetcher = (url) => fetch(url, post).then(r => r.json()) const { data, error } = useSWR('/api/post', fetcher, { shouldRetryOnError: false }) if (error) return <p>failed to load</p> if (!data) return <p>loading...</p> return <p>{data}</p> } export default Page
fetchを利用してPOSTしています。
今回は簡単に確認するため、bodyに固定のテキストを設定しています。通常はinputやtextareaのフォームからデータを設定するなどが多いと思います。
useSWR
の第3引数にオプションを設定しています。shouldRetryOnError
はフェッチでエラーが発生した場合にリトライするかのオプションです。falseですとリトライされません。
- src/pages/api/post.js
const handler = async(req, res) => { const data = req.body res.status(200).json(`/api/postで「${data}」を受け取りました`) } export default handler
今回はPOSTできているか確認するため、受け取ったデータを含めたテキストを返しています。通常はここからDBを操作して結果を返すなどが多いと思います。
req.body
でPOSTのbodyが読み取れます。
以上で/post
にアクセスすると、/api/postで「postページからの投稿」を受け取りました
と表示されます。
動的なページからPOSTする
Dynamic Routes
を利用して、動的なページからPOSTできるか確認します。
API(src/pages/api/post.js
)は静的なページと同じものを利用します。
- src/pages/[slug].js
import { useRouter } from 'next/router' import useSWR from 'swr' const Page = () => { const { slug } = useRouter().query const post = { method: 'POST', headers: { 'Content-Type': 'application/json'}, body: JSON.stringify(`${slug}ページからの投稿`), } const fetcher = (url) => fetch(url, post).then(r => r.json()) const { data, error } = useSWR(slug ? '/api/post' : null, fetcher, { shouldRetryOnError: false }) if (error) return <p>failed to load</p> if (!data) return <p>loading...</p> return <p>{data}</p> } export default Page
useRouter
を利用してslug(query)を読み取ります。この状態で/slug01
にアクセスすると/api/postで「slug01ページからの投稿」を受け取りました
と表示されます。
useSWRの第1引数にslugを渡しますが、useRouter().queryは初回にundefinedが返るため、そのままuseSWRを利用するとエラーになります。
そのためslugがundefinedの場合はnull
としてリクエストが開始されないようにしています。
Readだけでしたら動的なAPI Routesが楽な場合が多いですが、POSTが必要でしたら上記のようにエンドポイント側は固定にする方が簡潔な場合もあります。