Express to Next-Connect Migration Guide

ReactJS Jun 29, 2023
credit: en.wikipedia.org

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.

next-connect
The method routing and middleware layer for Next.js (and many others). Latest version: 1.0.0, last published: 2 months ago. Start using next-connect in your project by running `npm i next-connect`. There are 40 other projects in the npm registry using next-connect.

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.

Tags

TeamCMD

We are CODEMONDAY team and provide a variety of content about Business , technology, and Programming. Let's enjoy it with us.