1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00
next.js/examples/custom-server-fastify/server.js
Brian Kim 0298c722b1 improve custom-server-fastify example (#4805)
I’ve been experimenting with Next.js and Fastify and I made the following changes to the Fastify example based on what I found:

### Use Fastify’s plugin API
IMO putting Fastify’s listen call in a promise callback is an anti-pattern, b/c the Fastify plugin API is meant to solve the problem of async server bootstrapping.

[From Fastify’s Getting Started docs](https://www.fastify.io/docs/latest/Getting-Started/):
> Fastify provides a foundation that assists with the asynchronous bootstrapping of your application.

### Set reply.sent in handlers which return promises

[From Fastify’s Routes docs](https://www.fastify.io/docs/latest/Routes/#promise-resolution):
> If your handler is an `async` function or returns a promise, you should be aware of a special behaviour which is necessary to support the callback and promise control-flow. If the handler's promise is resolved with `undefined`, it will be ignored causing the request to hang and an *error* log to be emitted.
>
> 1. If you want to use `async/await` or promises but respond a value with `reply.send`:
>     - **Don't** `return` any value.
>     - **Don't** forget to call `reply.send`.
> 2. If you want to use `async/await` or promises:
>     - **Don't** use `reply.send`.
>     - **Don't** return `undefined`.

`app.render` returns a promise which contains undefined, so returning it in a Fastify handler will log an error. However, returning anything besides undefined will cause Fastify to try to write to the response which Next.js has already ended. The solution is to manually set the `reply.sent` flag to true when any Next.js rendering promise is fulfilled as an alternative to calling `reply.send`.

### Make Next.js handle 404 errors
This allows any route to throw a NotFound error and let Next.js handle the rendering of the 404 page.

### Make Next.js handle any route which starts with `_next` in dev
This prevents dev routes from being caught by user-defined routes.
2018-07-19 21:27:22 +02:00

57 lines
1.4 KiB
JavaScript

const fastify = require('fastify')({ logger: { level: 'error' } })
const Next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
fastify.register((fastify, opts, next) => {
const app = Next({ dev })
app.prepare()
.then(() => {
if (dev) {
fastify.get('/_next/*', (req, reply) => {
return app.handleRequest(req.req, reply.res)
.then(() => {
reply.sent = true
})
})
}
fastify.get('/a', (req, reply) => {
return app.render(req.req, reply.res, '/b', req.query)
.then(() => {
reply.sent = true
})
})
fastify.get('/b', (req, reply) => {
return app.render(req.req, reply.res, '/a', req.query)
.then(() => {
reply.sent = true
})
})
fastify.get('/*', (req, reply) => {
return app.handleRequest(req.req, reply.res)
.then(() => {
reply.sent = true
})
})
fastify.setNotFoundHandler((request, reply) => {
return app.render404(request.req, reply.res)
.then(() => {
reply.sent = true
})
})
next()
})
.catch((err) => next(err))
})
fastify.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})