Next.jsでhealth checkを実装する

概要

Next.jsでhealth checkを実装する。
k8s上で動かすという要件を想定する。

下記exampleを利用する。 https://github.com/vercel/next.js/tree/canary/examples/with-docker

環境

Next.js v10.0.1
Node.js v14.15.0
NPM v6.14.8

結論

API Routesを使う

API Routes: Introduction | Next.js

方法1

API Routesを使う

$mkdir pages/_
$touch pages/_/healthz.js
$tree pages/
pages/
├── api
│   └── _
│       └── healthz.js
└── index.js

healthz.js

export default function handler(req, res) {
  res.statusCode = 200;
  res.setHeader("Content-Type", "application/json");
  res.end(JSON.stringify({ status: "ok" }));
}

コンテナのbuildと起動

$docker build -t next-app .

$docker run --rm -it \
  -p 3000:3000 \
  next-app
$curl localhost:3000/api/_/healthz
{"status":"ok"}

f:id:mMQnaZ7vL2DWkoU:20201111223742p:plain
ブラウザアクセス

方法2

pageを作る

下記がヒットしたので試す。
reactjs - How to set up an endpoint for Health check on Next.js? - Stack Overflow

ディレクトリ構成

$tree pages/
pages/
├── api
├── index.js
└── ping
    └── index.js
// health check URL
function Ping() {}

// This gets called on every request
export async function getServerSideProps(context) {
  context.res.headers["content-type"] = "json";
  context.res.end("pong");
  return { props: {} };
}

export default Ping;

コンテナのbuildと起動

$docker build -t next-app .

$docker run --rm -it \
  -p 3000:3000 \
  next-app
$curl localhost:3000/ping
pong

f:id:mMQnaZ7vL2DWkoU:20201111225649p:plain
ブラウザアクセス

まとめ

ビルドの結果API Routesはフロントエンドのバンドルサイズに影響を与えない事がわかる。

They are server-side only bundles and won’t increase your client-side bundle size.

https://nextjs.org/docs/api-routes/introduction
liveness probeとrediness probe用のpageを追加しても微々たる差なので気にしなくても良い。
ただ本来の使い方を考慮するとAPI Routesで実装したほうが良いだろう。

$npm run build
Page                                                           Size     First Load JS
┌ ○ /                                                          327 B          60.4 kB
├ ○ /404                                                       3.44 kB        63.6 kB
├ λ /api/_/healthz                                             0 B            60.1 kB
└ λ /ping                                                      211 B          60.3 kB