7839

雑草魂エンジニアブログ

【Next】API Routes と next-connect を使ったフロントエンド爆速開発

Next.js のカンファレンス Next.js Conf。OGPのチケットがカッコ良すぎて、すごい盛り上がりのようだ。デザインセンスが良すぎる。私もチケット欲しさに、即座に登録した。オンライン開催とのことで、当日が楽しみだ。登録がまだの方は、是非、下記からどうぞ。

nextjs.org

ということで、今回は Next.js の便利な機能である「API Routes」を紹介する。API Routes は、Next.jsを使用してAPIを構築することができる機能である。用途は以下が考えられる。

  • フロントエンド開発のモックサーバーとしての利用
  • BFF(Backends For Frontends)でAPIサーバーとしての利用

私は現在、モックサーバーとして利用しているが、簡単に構築できる上に、Next.js のフレームワークの中に用意されているのが便利すぎる。バックエンドのAPIを待たずして、フロントエンドだけでモックサーバーがサクッとできてしまえば、爆速で開発できる気分だw(他人に左右されず、自分のリズムで開発できるという意味で。また、好きなようにダミーデータをSQLではなく、JSのコードで操作できるのは、開発がしやすい。)

API Routes

nextjs.org

Next.js は、Nuxt.js と同様に、pages ディレクトリ内のファイル構造に従い、自動的にルーティングが設定される。そして、API Routes は、pages/api 以下のファイル構造に従い、APIのエンドポイント api/* が設定される。これまで Express やその他サーバーを別に立ててAPIサーバーとしていたのが、Next.js のみで完結することができる。

pages/
 ├ users/
 │  ├ index.tsx  ← http://localhost/users のページ 
 |  └ [id]/
 │    └ index.tsx  ← http://localhost/users/id のページ 
 └ api/
    └ users/
      ├ index.ts  ← http://localhost/api/users のAPIエンドポイント[userId]/
        └ index.ts  ← http://localhost/api/users/userId のAPIエンドポイント

API の処理の実装に関しては、(req, res) を受け取り、APIとして返却したい内容を res に追加する関数を作り、export するだけである。それだけで API として機能する。next server もしくは custom serveryarn dev で起動するだけでよく、APIも、フロントエンドのサーバーも集約できているので、楽チンである。

import { NextApiRequest, NextApiResponse } from 'next'
const handler = (req: NextApiRequest, res: NextApiResponse) => {
  switch (req.method) {
    case 'GET': {
      // データの取得処理
      res.status(200).json(result)
      break
    }
    case 'PUT': {
      // データの更新処理
      res.status(200).json(result)
      break
    }
    default: {
      res.setHeader('Allow', ['GET', 'PUT'])
      res.status(405).json({ message: `Method ${method} Not Allowed` })
    }
  }
}
export default handler

req に関して(詳細はこちらから

  • req.method:HTTPメソッドを確認することができる
  • req.headers:ヘッダーの中身を確認することができる
  • req.cookies:HTTP Cookieのオブジェクトを得ることができる
  • req.query:クエリのオブジェクトで得ることができる
  • req.body:POST送信された、ボディの中身を得ることができる

res に関して(詳細はこちらから

  • res.status(code):HTTP Status Codeを指定できる
  • res.json(json):JSONレスポンスを送信できる
  • res.send(body):HTTPレスポンスを送信できる(bodyには、文字列、オブジェクト、バイナリーデータ(Buffer)を入れることができる)
  • res.redirect([status,] path):特定のパスに対してリダイレクトできる。statusのデフォルトは、[307]となっている。

next-connect

上記で示したように、これから紹介するモジュールを使わなくても、簡単に実装ができる。ただし、「next-connect」を使うことでより簡単に、また複雑な処理をしようとした場合に思い通りに実装ができるので使うことをオススメする。特に、認証機能やDBからデータを取得する場合などには、ミドルウェアを実装する事になるが、「next-connect」を使うことで、簡潔に実装することができる。

www.npmjs.com

実装例としては、API全体での共通の処理を handler に記載し、それぞれのエンドポイントではその handler を使って各HTTPメソッドに対する処理を記載するようにしている。

Express を使ったことがある人であれば、ミドルウェアは同じように、use メソッドを使って追加することができる。今回は、ミドルウェアを全体に適応させることを想定して、handlerに記載している。もちろん、各エンドポイントで個別にミドルウェアを追加したい場合は、handler.use(middleware()) で追加が可能である。

import { NextApiRequest, NextApiResponse } from 'next'
import nextConnect from 'next-connect'
const handler = nextConnect<NextApiRequest, NextApiResponse>({
  onError(error, req, res) {
    // エラーが発生した場合の処理
  },
  onNoMatch(req, res) {
    // エンドポイントがない場合の処理
  },
}).use((req, res, next) => {
  // ミドルウェアの処理を追加する
    - headerのAuthenticationでリクエストの認証をする
    - DBを接続する  など
})
export default handler

各HTTPメソッドに対する処理に関しても、メソッドチェーンで実装でき、上記の switch 文での分岐よりも、簡潔に書くことができる。

import handler from 'api/handler'
export default handler
  .get(async (req, res) => {
    // GETの処理
    res.json(data)
  })
  .post(async (req, res) => {
    // POSTの処理
    res.json(data)
  })

サンプルコード

今回のサンプルコードは、どちらも Next.js の公式の Example である。

  • API routes with REST

    • DBを使わずに、変数でデータを保持して簡易にRESTなAPIを実装できている
    • リレーショナルのないデータであれば、このような実装で問題ない気がしている
  • next-connect + Passport認証

    • Passport.jsを使った認証のサンプル

まとめ

今回は、API Routes と next-connect についてまとめた。是非、これらを使って、フロントエンドの爆速開発を実現して欲しい。改めて、Next.js は本当に集約されていて、便利であると感じた。もっと使い込んで、使いこなせるようになっていきたい。

それでは、ステキな開発ライフを。