Next.jsでAPIのエンドポイントを組む際はnext-connectを使うと良いよ

2021-12-09

Next.js で API のエンドポイントを組むの場合、なかなかしっくり来る組み方に出会えていませんでした。

そんな中 [next-connect] を使ってみると、かなりしっくり来る組み方ができたので紹介をば。

まずは Next.js の 公式ドキュメント に沿ってみるとこんな感じになります。

function handler(req, res) { const { method } = req; const { idToken } = nookies({ req }); // idToken のあれこれ if (method === "GET") { // GET のあれこれ res.status(200).json({ hoge: "hoge" }); } else if (method === "POST") { // POST のあれこれ res.status(200).json({ fuga: "fuga" }); } } export default handler;

上記を見ると悪くなさそうに見えるのですが、TypeScript となるとそうもいきません。

import type { NextApiRequest, NextApiResponse } from "next"; type GetData = { hoge: string; }; type PostData = { fuga: string; }; function handler( req: NextApiRequest, res: NextApiResponse<GetData | PostData> ) { const { idToken } = parseCookies({ req }); const { method } = req; // idToken のあれこれ if (method === "GET") { // GET のあれこれ res.status(200).json({ hoge: "hoge" }); } else if (method === "POST") { // POST のあれこれ res.status(200).json({ fuga: "fuga" }); } } export default handler;

結構ごちゃついてくる印象がありますが、いかがでしょうか。

で、これを next-connect を使って書き換えるとこんな感じになります。

import type { NextApiRequest, NextApiResponse } from "next"; import nc from "next-connect"; type GetData = { hoge: string; }; type PostData = { fuga: string; }; const handler = nc<NextApiRequest, NextApiResponse<GetData | PostData>>().use( // ここを middleware として共通化しても良い (req, _, next) => { const { idToken } = parseCookies({ req }); // idToken のあれこれ next(); } ); type ExtendedGetRequest = Record<string, never>; type ExtendedGetResponse = { json(body: GetData): void; }; handler.get<ExtendedGetRequest, ExtendedGetResponse>( // 型をつけなくても良い async (_, res: NextApiResponse<GetData>) => { // GET のあれこれ res.status(200).json({ hoge: "hoge" }); } ); type ExtendedPostRequest = Record<string, never>; type ExtendedPostResponse = { json(body: PostData): void; }; handler.post<ExtendedPostRequest, ExtendedPostResponse>( // 型をつけなくても良い async (_, res: NextApiResponse<PostData>) => { // POST のあれこれ res.status(200).json({ fuga: "fuga" }); } ); export default handler;

もちろん getpost の処理をそのままチェーンで繋ぐことも可能です。

で、next-connect のもっとも大きいメリットが、use の引数を middleware として共通化することも可能な点です。

他にもエラーハンドリングの書きっぷりも強いですし、共通化にも対応しているのがすごいですね。

さらに getServerSideProps でも呼び出し可能なので、middleware をすべて共通化すると良い感じです。

ということで、今後はこれを使って書いていこうかなーと思います。

© 2018 kk-web