千里の道も1commitから

関西在住のWebエンジニアです。長らくブログをサボっていたので、1日1記事、1commitを目標にゆるりと頑張ります。積み重ねが研鑽となると信じて

Next.jsでExpressを導入する(カスタムサーバー)

Next.jsではカスタムサーバーで、サーバーサイドをNode.jsで実装することが可能です。 これはかなり優秀で、pagesディレクトリ以下はNext.jsのルーティング、apiディレクトリ以下はNode.jsのルーティングというように直感的に分けることが可能です。 nextjs.org

Next.jsはhttpの例ですが、 express でも導入することが可能です。

カスタムサーバーでExpressを導入する

GitHub - gonta616/nextjs-study at 069e9924a9314a8418f4c930abcaf446675802e7

の続きです。

npm i express express-session body-parser cross-env 

server.jsを作ります。以下のようにNext.jsはexpressのルーティングをラップしているだけで、非常に短いコードでカスタムサーバーを構築することが可能です。
expressのエコシステムも問題なく使うことができます。

const express = require('express')
const bodyParser = require('body-parser')
const session = require('express-session')
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express()
  server.use(bodyParser.json())
  server.use(session({
    secret: 'zZAai8301bSnuA8sabUwabxe3',
    resave: false,
    saveUninitialized: false,
    cookie: { maxAge: 60000 }
  }))

  server.all('*', (req, res) => {
    return handle(req, res)
  })

  server.listen(port, err => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
})

続いて、package.jsonを書き換えます。

  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "cross-env NODE_ENV=production node server.js",

サーバーを起動すると、変わらずpages以下にアクセスできることがわかります。

npm run dev

肝はこの部分。getRequestHandler でhandlerを作成し、serverのミドルウェアでreq, resを喰わせています。handleはNext.js内でURLを解釈しroutingします。

const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express()

  server.all('*', (req, res) => {
    return handle(req, res)
  })

デモ用のrouterを作成します。

const express = require('express')
const router = express.Router()

router.get('/', (req, res, next) => {
  res.json(`GET OK! query is ${req.query}`)
})

router.get('/:id', (req, res, next) => {
  res.json(`GET OK! params is ${req.params.id}`)
})

router.post('/', (req, res, next) => {
  res.json(`POST OK! params is ${req.body}`)
})

module.exports = router

server.jsでrouterをミドルウェアに登録します。

  server.use('/demo', demoRouter)
  server.all('*', (req, res) => {
    return handle(req, res)
  })

サーバーを再起動すると /demo 以下にアクセスできるようになります。
フロントはpages以下がになってるので、内部APIをカスタムサーバーのroutingに登録すると。綺麗に役割分担できそうです。

所感

  • Next.jsではExpressのカスタムサーバーを簡易に構築することができる
  • Expressのエコシステムが利用可能
  • Viewはpages、内部APIカスタムサーバーのapiと役割づけると良い

1日1コミット

Setup Custom server using express · gonta616/nextjs-study@7c7f8ef · GitHub