stegano / next-http-proxy-middleware Goto Github PK
View Code? Open in Web Editor NEWHTTP Proxy middleware available in API Middleware provided by Next.js.
HTTP Proxy middleware available in API Middleware provided by Next.js.
I want to handle the self response data (I want to do something like set a some data to cookie, etc...) in Next.js API Routes, but if I set it to true, none of the webOutgoing passes are called, that resulted in my request never being responded. What should I do?
const handleProxyInit = (proxy) => {
proxy.on('proxyRes', (proxyRes, req, res) => {
let body = [];
proxyRes.on('data', function (chunk) {
body.push(chunk);
});
proxyRes.on('end', function () {
body = Buffer.concat(body).toString('utf8');
// do something here
});
});
};
httpProxyMiddleware(req, res, {
...,
selfHandleResponse: true,
changeOrigin: true,
onProxyInit: handleProxyInit,
});
Dependabot is triggering a warning because of this package. Please update Dependencies.
(You can activate Dependabot in the Github settings for free for your repo)
Thanks
Dependabot cannot update node-notifier to a non-vulnerable version
The latest possible version that can be installed is 6.0.0 because of the following conflicting dependency:
[email protected] requires node-notifier@^6.0.0 via a transitive dependency on @jest/[email protected]
The earliest fixed version is 8.0.1.
Hello,
what should one do in order to rewrite paths for different targets?
I'm trying to use this library to proxy websockets. I've tried several approaches but so far none of them are working.
import { NextApiRequest, NextApiResponse } from "next";
import httpProxyMiddleware from "next-http-proxy-middleware";
export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
};
export default async (req: NextApiRequest, res: NextApiResponse) => {
return httpProxyMiddleware(req, res, {
target: "ws://localhost:3001/graphql",
ws: true,
});
};
Is it possible to do it with this library?
Can this be used in production? We have an next.js app and a nestjs server. We have cookies running to and from both of them so different domains are a problem. This seems to fix this issue. Is this stable enough to be used in production?
Hey there,
Getting the message in the subject after every request in my dev env when running npm run dev.
How do I make it go away?
Thanks
Unable to use path rewrite to external endpoint.
using vanila http-proxy-middleware
it is possible using router
https://github.com/chimurai/http-proxy-middleware/blob/c935888ea7135365bea3c4c81e4ffe48f359a670/examples/response-interceptor/index.js#L39
Pseudo code
// src/pages/api/demo.ts
export default (req: NextApiRequest, res: NextApiResponse) =>
httpProxyMiddleware(req, res, {
timeout: 3000,
target: 'http://localhost:8080',
router: {
'/api/demo': 'https://google.com',
},
pathRewrite: {
'/api/demo': '',
},
}).catch(async (error) => {
res.end(error.message);
console.log(error);
});
As a workaround i create multiple files with different target option
I was using this module like so:
import httpProxyMiddleware from 'next-http-proxy-middleware';
import { NextApiRequest, NextApiResponse } from 'next';
import { getSession } from '@auth0/nextjs-auth0';
import * as Sentry from '@sentry/node';
import { initSentry } from 'src/utils/sentry';
export default async (req: NextApiRequest, res: NextApiResponse) => {
const session = getSession(req, res);
return new Promise((resolve) =>
httpProxyMiddleware(req, res, {
target: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: { Authorization: `Bearer ${session?.idToken}`, 'Content-Type': 'application/json-patch+json' },
}).catch(async (error) => {
initSentry();
Sentry.captureException(error);
await Sentry.flush(2000);
return resolve(error);
})
);
};
And as you can see in memory usage graph it is spikes and some server restarts.
But when I switched to middleware like so
import { NextApiRequest, NextApiResponse } from 'next';
import { getSession } from '@auth0/nextjs-auth0';
import { createProxyMiddleware } from 'http-proxy-middleware';
import * as Sentry from '@sentry/node';
import { initSentry } from 'src/utils/sentry';
export const config = {
api: {
bodyParser: false,
externalResolver: true,
},
};
export default createProxyMiddleware({
target: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: {
'Content-Type': 'application/json-patch+json',
},
selfHandleResponse: false,
changeOrigin: true,
xfwd: true,
secure: true,
proxyTimeout: 3000,
ws: true,
onProxyReq: (proxyReq, req: Request & NextApiRequest, res: Response & NextApiResponse) => {
proxyReq.setHeader('Authorization', `Bearer ${getSession(req, res)?.idToken}`);
},
onError: (err, req: Request & NextApiRequest, res: Response & NextApiResponse) => {
initSentry();
Sentry.captureException(err);
Sentry.flush(2000);
res.end('Something went wrong.');
},
});
the memory usage becomes stable. Also got correct response headers from API like 404
I am experiencing problem that I am not able to add any custom headers. I have made a quick look on your code and I don't see any action with headers on proxy request ...
The “newest” release is versioned 1.0.8-hotfix.1
but that's a pre-release version identifier, per https://semver.org/#spec-item-9
So releasing it did not in fact hotfix anything — a package.json
that specifies ^1.0.8
will install 1.0.8
, not 1.0.8-hotfix.1
. This is probably not what was intended. :)
Thanks for open sourcing this library, saved me quite some time while implementing my API proxy.
While working with multipart/form-data
requests i've noticed that the Next.js bodyParser tries to parse the body, causing it to corrupt the binary content of all files in the request. Therefore (in my case) it's desired to disable the bodyParser entirely in the API route (https://nextjs.org/docs/api-routes/api-middlewares#custom-config).
export const config = {
api: {
bodyParser: false
}
};
This library handles all other requests/content-types correctly. Perhaps it would be an idea to document this to safe others some time with similar issues.
Installing this package yields the following warning:
npm WARN deprecated @types/[email protected]: This is a stub types definition. next provides its own type definitions, so you do not need this installed.
You might want to remove this line:
next-http-proxy-middleware/package.json
Line 18 in 013caa3
It could also help to move all @types/
dependencies to devDependencies.
It would be great to have the possibility to chain proxy middlewares like this:
httpProxyMiddleware(req, res, {
target: process.env.target1,
pathRewrite: [{
patternStr: "^/api", replaceStr: "",
}],
}).than((response)=>httpProxyMiddleware(req, response, {
target: process.env.target2,
pathRewrite: [{
patternStr: "^/s3", replaceStr: "",
}],
}))
What is the proper way of doing this?
I have already installed next-http-proxy-middleware and using it on my nextjs app to connect it to my nodejs express which is on another domain. My express API is using JWT cookie for sign in/sign out . I am trying to transfer it to front-end but no chance . Is this possible ?
This is my current setup :
import { NextApiRequest, NextApiResponse } from "next";
import httpProxyMiddleware from "next-http-proxy-middleware";
export default (req: NextApiRequest, res: NextApiResponse) =>
httpProxyMiddleware(req, res, {
target: "http://my-nodejs-api-example.herokuapp.com", changeOrigin: true,
pathRewrite: {
"^/api/": '/api/v1/',
},
});
I am getting error with my page
./pages/api/[...all].ts:13:10
Type error: This expression is not callable.
Type 'typeof import("/Users/joeyoung/_WORKING/joegyoung/node_modules/next-http-proxy-middleware/src/index")' has no call signatures.
11 | } = req;
12 |
> 13 | return httpProxyMiddleware(req, res, {
| ^
14 | // You can use the `http-proxy` option
15 | target: `http://localhost:9000/.netlify/functions/${all}`,
16 | pathRewrite: {
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
This is the source
import { NextApiRequest, NextApiResponse } from "next";
import httpProxyMiddleware from "next-http-proxy-middleware";
const isDevelopment = process.env.NODE_ENV === "development";
const isProduction = process.env.NODE_ENV === "production";
export default (req: NextApiRequest, res: NextApiResponse) => {
if (isDevelopment) {
const {
query: { all },
} = req;
return httpProxyMiddleware(req, res, {
// You can use the `http-proxy` option
target: `http://localhost:9000/.netlify/functions/${all}`,
pathRewrite: {
"^/api+": "",
},
});
} else {
res.status(404).send(null);
}
};
What am I needing to do?
The examples for using next-http-proxy-middleware should include importing (or requiring) the module. There is no indication if this is a named or default export, or if the user can use ES modules or commonJS.
Thank you for your time maintaining this project
Hi,
There's an error in the rewritePath method. It already returns after the first replacement and thus never checks other rewrites.
Example:
Wrong: rewritePath('/api/test/xy/', { '/$': '', '^/api/test/': '' }) -> /api/test/xy
Correct: rewritePath('/api/test/xy/', { '/$': '', '^/api/test/': '' }) -> xy
export const rewritePath = (
url: string,
pathRewrite: { [key: string]: string }
) => {
for (let patternStr in pathRewrite) {
const pattern = RegExp(patternStr);
const path = pathRewrite[patternStr];
if (pattern.test(url as string)) {
return url.replace(pattern, path); <--- returns to early
}
}
return url;
};
possible fix:
export const rewritePath = (url: string, pathRewrite: { [key: string]: string }): string => {
let rewrittenUrl = url;
for (let patternStr in pathRewrite) {
const pattern = new RegExp(patternStr);
const path = pathRewrite[patternStr];
if (pattern.test(url as string)) {
rewrittenUrl = rewrittenUrl.replace(pattern, path);
}
}
return rewrittenUrl;
};
Hello,
I need help and it is that when requesting an endpoint that ends in slash (backend in Django Rest Framework) the proxy removes the slash when I put it in the fetch url.
A solution would be to remove the slash in django rest framework and set APPEND_SLASH = False but I lose the redirection when the request is made with the slash.
RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to localhost:8000/api/auth/jwt/create/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
The type requests in the new route system changed from NextApiequest to NextRequest
and the middleware seems cannot work accordingly. any workaround?
I think it would be useful to add onProxyReq
and onProxyRes
options in the constructor function:
httpProxyMiddleware(req, res, {
// You can use the `http-proxy` option
target: 'https://www.example.com',
// In addition, you can use the `pathRewrite` option provided by `next-http-proxy-middleware`
pathRewrite: [{
patternStr: '^/api/new',
replaceStr: '/v2'
}, {
patternStr: '^/api',
replaceStr: ''
}],
+ onProxyReq: (proxyReq, req, res) => {...},
+ onProxyRes: (proxyRes, req, res) => {...},
})
This will allow more fine-grained request and response rewriting.
Hi,
I was using the old signature for pathRewrite
of a plan object, with the key as the test pattern & the value being the replacement string.
This was working great with v1.0.*
of the library, but it seems like the new v1.1.*
introduce change broke this compatiblity.
httpProxyMiddleware(req, res, {
target: `https://${shop.name}/admin/api/2021-10/graphql.json`,
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": shop.accessToken,
},
changeOrigin: true,
ws: true,
pathRewrite: {
"^/api/graphql": "",
},
});
I attempted to use the new Array based syntax:
pathRewrite: [{
patternStr: "^/api/graphql",
replaceStr: ""
}],
});
But the without being able to visualize the request, I'm not sure why that request is being rejected by the host.
I just know that downgrading and keeping the old signature works for my case.
Leaving this for documentation purposes, maybe I'll get around to adding a debugging mode or something to view the request's parameters easier.
First of all: nice lib. AFAICT it's the only clean middleware out there that allows to update the request's headers with NextJS without errors.
I do encounter issues with your middleware though.
I have a fairly simple proxy setup for an API with a dynamic route (using SWR
on the client side):
import type { NextApiRequest, NextApiResponse } from 'next'
import jwt from 'next-auth/jwt'
import httpProxyMiddleware from 'next-http-proxy-middleware';
export default async (req: NextApiRequest, res: NextApiResponse) => {
const { accessToken } = await jwt.getToken({ req: req, secret: "CHANGE_ME" })
return httpProxyMiddleware(req, res, {
target: 'https://whatever.com',
pathRewrite: { "^/before": '/after' },
headers: { Authorization: `Bearer ${accessToken}` },
})
}
When sending requests via to the proxy for with the same path, it works nicely. When requests with different paths go through the middleware, I see the following error (not right away, after a couple of minutes):
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at new NodeError (node:internal/errors:278:15)
at write_ (node:_http_outgoing:718:11)
at ClientRequest.write (node:_http_outgoing:677:15)
at ProxyServer.<anonymous> (.../next-http-proxy-middleware/build/index.js:1:2419)
at ProxyServer.emit (.../eventemitter3/index.js:210:27)
at ClientRequest.<anonymous> (.../http-proxy/lib/http-proxy/passes/web-incoming.js:133:16)
at ClientRequest.emit (node:events:388:22)
at tickOnSocket (node:_http_client:781:7)
at onSocketNT (node:_http_client:820:5)
at processTicksAndRejections (node:internal/process/task_queues:81:21) {
code: 'ERR_STREAM_WRITE_AFTER_END'
}
And prior to that, NextJS's server shows this kind of warning:
[...]
API resolved without sending a response for some/target/url, this may result in stalled requests
[...]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.