Proxy middleware in Next JS 9: express vs api

Alexander Konovalov
3 min readJun 17, 2020

Hi, very often every frontend developer has an issue using requests to the backend service. And sometimes we can’t use backend service directly in our development especially locally, because of the CORS problem. The problem can be solved in some ways, and in this article, I will tell about one of the solutions — using a proxy service for requests in Next JS 9.

If you are lazy to read the entire article you can find all Github gists at the end of the article 😉

First of all, we need to install proxy middleware for our requests. I use http-proxy-middleware, you can choose another one.

npm i http-proxy-middleware

In this article, I’ll compare two ways of using proxy middleware local in my Next JS app: node express vs new builtin api feature.

Express

First, install express:

npm i express

Add local-server.js at the root of the project.

// local-server.jsconst express = require('express');
const next = require('next');
const { createProxyMiddleware } = require('http-proxy-middleware');

const conf = require('./next.config');

const dev = process.env.NODE_ENV !== 'production';
const port = parseInt(process.env.PORT, 10) || 3000;

const app = next({ dev, conf });
const handler = app.getRequestHandler();

const devProxy = {
[`/${process.env.API_PATH}`]: {
target: process.env.BACKEND_API,
pathRewrite: {
[`^/${process.env.API_PATH}`] : '',
},
changeOrigin: true,
}
};

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

// Set up the proxy.
if (dev && devProxy) {
Object.keys(devProxy).forEach(context => {
server.use(createProxyMiddleware(context, devProxy[context]))
})
}

server.all('*', (req, res) => handler(req, res))

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

Add external resolver for api requests in next.config

// next.configmodule.exports = {
api: {
externalResolver: true,
},
}

And finally, change your package.json to run this local-server.js

// package.json"scripts": {
...
"dev": "node local-server.js",
...
},

New api feature in Next JS with next-connect

First, install next-connect to use proxy middleware in express like way:

npm i next-connect

I have this folder structure in my next js project and use slug for all api requests excluding other defined entities (booking, teacher, cards).

Using slug for api

I use proxy middleware only for local development, that why I compare my environment variable with local development.

// [...slug].jsimport nc from 'next-connect'

const dev = process.env.NODE_ENV !== 'production'

const handler = nc()

if (dev) {
const { createProxyMiddleware } = require('http-proxy-middleware')
handler.use(createProxyMiddleware({
target: process.env.BACKEND_API,
pathRewrite: {
[`^/${process.env.API_PATH}`]: '',
},
changeOrigin: true,
}))
}

export default handler

Add the option “optionalCatchAll” to next.config

// next.configmodule.exports = {
optionalCatchAll: true
}

Conclusion

You can use both ways for your necessity. But for me, the api feature way is more interesting and clear, because it is a built-in method and more compatible with the NextJS.

Links

Expresshttps://gist.github.com/elcodabra/79959f329e564a49a927d8db51f68960

Api and next-connecthttps://gist.github.com/elcodabra/43ef0157464d92bfe1e6eb7b40c94771

Thank you for reading! Subscribe to me on FB, LinkedIn, and of course on Medium. A lot of new posts about design & development will be there.

--

--