Comparing version
@@ -406,17 +406,25 @@ 'use strict'; | ||
const defaultOption = () => ({ | ||
target: '', | ||
enableLogger: true, | ||
}); | ||
const createProxyEventHandler = (options) => { | ||
const finalOptions = Object.assign({ enableLogger: true }, options); | ||
const { target, pathFilter, pathRewrite, enableLogger, loggerOptions } = finalOptions; | ||
if (!target) { | ||
throw new Error(ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING); | ||
} | ||
const logger = createLogger({ | ||
enableLogger, | ||
loggerOptions, | ||
}); | ||
const multiOptions = Array.isArray(options) ? options : [options]; | ||
const finalMultiOptions = multiOptions.map((v) => Object.assign(defaultOption(), v)); | ||
return async (event) => { | ||
const { req } = event.node; | ||
const path = getUrlPath(req.url, target); | ||
const proxyRequestOptions = createProxyRequestOptions(event, finalOptions); | ||
if (isTargetFilterPath(path, { pathFilter, req })) { | ||
const finalOptions = finalMultiOptions.find((v) => { | ||
const path = getUrlPath(req.url, v.target); | ||
return isTargetFilterPath(path, { pathFilter: v.pathFilter, req }); | ||
}); | ||
if (finalOptions) { | ||
const { target, pathRewrite, enableLogger, loggerOptions } = finalOptions; | ||
if (!target) { | ||
throw new Error(ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING); | ||
} | ||
const logger = createLogger({ | ||
enableLogger, | ||
loggerOptions, | ||
}); | ||
const path = getUrlPath(req.url, target); | ||
const pathRewriter = createPathRewriter(pathRewrite, logger); | ||
@@ -429,2 +437,3 @@ let rewritedPath = path; | ||
logger && logger.success('proxy to target url:', targetUrl); | ||
const proxyRequestOptions = createProxyRequestOptions(event, finalOptions); | ||
return h3.proxyRequest(event, targetUrl, proxyRequestOptions); | ||
@@ -431,0 +440,0 @@ } |
@@ -40,3 +40,3 @@ import { H3Event, ProxyOptions, EventHandler } from 'h3'; | ||
type CreateProxyEventHandler = ( | ||
options: CreateProxyEventHandlerOptions | ||
options: CreateProxyEventHandlerOptions | CreateProxyEventHandlerOptions[] | ||
) => EventHandler | ||
@@ -43,0 +43,0 @@ |
@@ -404,17 +404,25 @@ import isGlob from 'is-glob'; | ||
const defaultOption = () => ({ | ||
target: '', | ||
enableLogger: true, | ||
}); | ||
const createProxyEventHandler = (options) => { | ||
const finalOptions = Object.assign({ enableLogger: true }, options); | ||
const { target, pathFilter, pathRewrite, enableLogger, loggerOptions } = finalOptions; | ||
if (!target) { | ||
throw new Error(ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING); | ||
} | ||
const logger = createLogger({ | ||
enableLogger, | ||
loggerOptions, | ||
}); | ||
const multiOptions = Array.isArray(options) ? options : [options]; | ||
const finalMultiOptions = multiOptions.map((v) => Object.assign(defaultOption(), v)); | ||
return async (event) => { | ||
const { req } = event.node; | ||
const path = getUrlPath(req.url, target); | ||
const proxyRequestOptions = createProxyRequestOptions(event, finalOptions); | ||
if (isTargetFilterPath(path, { pathFilter, req })) { | ||
const finalOptions = finalMultiOptions.find((v) => { | ||
const path = getUrlPath(req.url, v.target); | ||
return isTargetFilterPath(path, { pathFilter: v.pathFilter, req }); | ||
}); | ||
if (finalOptions) { | ||
const { target, pathRewrite, enableLogger, loggerOptions } = finalOptions; | ||
if (!target) { | ||
throw new Error(ERRORS.ERR_CONFIG_FACTORY_TARGET_MISSING); | ||
} | ||
const logger = createLogger({ | ||
enableLogger, | ||
loggerOptions, | ||
}); | ||
const path = getUrlPath(req.url, target); | ||
const pathRewriter = createPathRewriter(pathRewrite, logger); | ||
@@ -427,2 +435,3 @@ let rewritedPath = path; | ||
logger && logger.success('proxy to target url:', targetUrl); | ||
const proxyRequestOptions = createProxyRequestOptions(event, finalOptions); | ||
return proxyRequest(event, targetUrl, proxyRequestOptions); | ||
@@ -429,0 +438,0 @@ } |
{ | ||
"name": "h3-proxy", | ||
"version": "1.10.0", | ||
"version": "1.11.0", | ||
"description": "A proxy event handler for h3, using proxyRequest.", | ||
@@ -27,3 +27,4 @@ "type": "module", | ||
"test:coverage": "yarn test -- --reporter verbose --coverage", | ||
"start": "node ./playground/main.js" | ||
"start": "node ./playground/main.js", | ||
"start:multi-target-usage": "node ./playground/multi-target-usage.js" | ||
}, | ||
@@ -30,0 +31,0 @@ "repository": { |
116
README.md
@@ -15,5 +15,7 @@ <p align="center"> | ||
- ✨ [Release Notes](./CHANGELOG.md) | ||
# Features | ||
- Powered by built-in `proxyRequest` of [h3](https://github.com/unjs/h3). | ||
- Powered by built-in [proxyRequest](https://github.com/unjs/h3/blob/main/src/utils/proxy.ts) of [h3](https://github.com/unjs/h3). | ||
- Support http(s) proxy via some simple [configurations](https://github.com/yisibell/h3-proxy#options). | ||
@@ -36,3 +38,3 @@ - Support logs via **consola**. | ||
# Usage | ||
# Basic usage | ||
@@ -48,2 +50,3 @@ ```ts | ||
// Define proxy event handler | ||
const proxyEventHandler = createProxyEventHandler({ | ||
@@ -58,2 +61,6 @@ target: `http://127.0.0.1:${port}`, | ||
// Add proxy middlewares | ||
app.use(eventHandler(proxyEventHandler)) | ||
// Define api routes | ||
app.use( | ||
@@ -64,7 +71,77 @@ '/test', | ||
app.use(eventHandler(proxyEventHandler)) | ||
createServer(toNodeListener(app)).listen(port) | ||
``` | ||
# Multiple proxy targets usage | ||
- Create multiple proxy **h3** event handler middleware. | ||
```ts | ||
import { createServer } from 'node:http' | ||
import { createApp, eventHandler, toNodeListener } from 'h3' | ||
import { createProxyEventHandler } from 'h3-proxy' | ||
const app = createApp() | ||
const port = process.env.PORT || 3000 | ||
// proxy to `http://127.0.0.1:${port}` | ||
const proxyEventHandler1 = createProxyEventHandler({ | ||
target: `http://127.0.0.1:${port}`, // http://127.0.0.1:3000 | ||
pathRewrite: { | ||
'^/api': '', | ||
}, | ||
pathFilter: ['/api/**'], | ||
}) | ||
// proxy to other target | ||
const proxyEventHandler2 = createProxyEventHandler({ | ||
target: `http://127.0.0.1:${port}/other-api-module`, | ||
pathRewrite: { | ||
'^/other-api': '', | ||
}, | ||
pathFilter: ['/other-api/**'], | ||
}) | ||
// Add proxy middlewares | ||
app.use(eventHandler(proxyEventHandler1)) | ||
app.use(eventHandler(proxyEventHandler2)) | ||
// Define api routes | ||
app.use( | ||
'/test', | ||
eventHandler(() => 'Hello world!') | ||
) | ||
app.use( | ||
'/other-api-module/some/path', | ||
eventHandler(() => 'Hello other API module!') | ||
) | ||
createServer(toNodeListener(app)).listen(port) | ||
``` | ||
- For `proxyEventHandler1`, The result of proxy request is as follows: | ||
`/api/test` -> `http://127.0.0.1:3000/test` | ||
- For `proxyEventHandler2`, The result of proxy request is as follows: | ||
`/other-api/some/path` -> `http://127.0.0.1:3000/other-api-module/some/path` | ||
- Or, using **Array** type options to define multiple proxy targets (added in v1.11.0). | ||
```ts | ||
const proxyEventHandler = createProxyEventHandler([ | ||
{ | ||
// options | ||
}, | ||
{ | ||
// other proxy target options | ||
} | ||
]) | ||
``` | ||
# APIs | ||
@@ -128,3 +205,9 @@ | ||
const pathFilter = function (path, req) { | ||
return path.match('^/api') && req.method === 'GET'; | ||
return path.match(/^\/api/) && req.method === 'GET'; | ||
// TIPS: if you are using it in nuxt-proxy-request | ||
// Pls use `new RegExp()` instead. | ||
// return path.match(new RegExp('^\/api')) && req.method === 'GET'; | ||
}; | ||
@@ -165,2 +248,4 @@ | ||
For the return value, Please refer to the source code of [proxyRequest of h3](https://github.com/unjs/h3/blob/main/src/utils/proxy.ts). | ||
```ts | ||
@@ -172,2 +257,8 @@ createProxyEventHandler({ | ||
// return your custom options of proxyRequest | ||
// eg: specify some request headers | ||
// return { | ||
// headers: {} | ||
// } | ||
return {} | ||
@@ -178,9 +269,18 @@ } | ||
# Framework Supports | ||
## Nuxt | ||
# CHANGE LOG | ||
- using [nuxt-proxy-request](https://github.com/yisibell/nuxt-proxy-request) module. | ||
- using `h3-proxy` directly in **Nuxt**. | ||
See <a href="./CHANGELOG.md">CHANGE LOG</a> here. | ||
Add a [server middleware](https://nuxt.com/docs/guide/directory-structure/server#server-middleware). | ||
# Framework Supports | ||
```ts | ||
// ~/server/middleware/proxy.ts | ||
- Nuxt: see [nuxt-proxy-request](https://github.com/yisibell/nuxt-proxy-request). | ||
import { createProxyEventHandler } from 'h3-proxy' | ||
export default defineEventHandler(createProxyEventHandler({ | ||
// options... | ||
})) | ||
``` |
39031
9.63%801
2.3%277
56.5%