Express to Next-Connect Migration Guide
For use case that need Next with some server that need to be more and a mere proxy, one solution is using Next-connect.
For alternative solution, we can use custom express server as a parent and support next
as a child as in Next.js doc here.
File routing
We will not use file routing under /api
but rather provide ‘match all’ single entry point to /api
and let next-connect handle it
/api
|__[[...slug]].js
in the [[...slug]].js
file we init the normal express routing
const handler = nc()
.use(someMiddleware())
.get((req, res) => {
res.send("Hello world");
})
Centralize Error handling
Next-connect support onError
method rather than Express’s 4 arguments error handler middleware
function onError(err, req, res, next) {
logger.log(err);
res.status(500).end(err.toString());
// OR: you may want to continue
next();
}
const handler = nc({ onError });
No Try-catch
The pattern that catch and pass to next(error)
is not in next-connect
try {
} catch(error) {
next(error)
}
rather it catch error automatically and send to onError
specified in nc({ onError })
Params
params work as expected by specify attachParams: true
const handler = nc({ attachParams: true })
.use("/api/hello", someMiddleware())
.get("/api/user/:userId", (req, res) => {
res.send(`Hello ${req.params.userId}`);
});
Getting session or credential
For getting server-side credential, the getServerSideProps
work well with nc.run
. Below is my example of checking whether user is logged in with express-session
export const requireLogin = (getServerSideProps) => async (context) => {
const { req, res } = context
const handler = nc().use(session)
try {
const response = await handler.run(req, res)
console.log(response)
console.log('req.session.isLogin', req.session.isLogin)
if (req.session.isLogin) {
// Continue on to call `getServerSideProps` logic
return await getServerSideProps({ ...context, isLogin: req.session.isLogin })
}
throw new Error('Not login')
} catch (error) {
console.log(error)
return {
redirect: {
destination: '/login',
permanent: false,
},
}
}
}
Then the usage in next
export const getServerSideProps = requireLogin((context) => {
... your other props here
return { props: {...} }
})
I write this to my future self when I might have to do this again and at that time I’m quite sure I will forget how to do it !
Hope this might help some friend out there too.
Cheers.