Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yisibell/h3-proxy
A http(s) proxy event handler for h3, using proxyRequest.
https://github.com/yisibell/h3-proxy
event-handler h3 http http-proxy https middleware nuxt nuxt3 proxy proxy-request
Last synced: about 1 month ago
JSON representation
A http(s) proxy event handler for h3, using proxyRequest.
- Host: GitHub
- URL: https://github.com/yisibell/h3-proxy
- Owner: yisibell
- License: mit
- Created: 2023-03-14T09:27:22.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-28T06:12:48.000Z (8 months ago)
- Last Synced: 2024-10-03T09:06:30.084Z (3 months ago)
- Topics: event-handler, h3, http, http-proxy, https, middleware, nuxt, nuxt3, proxy, proxy-request
- Language: TypeScript
- Homepage:
- Size: 450 KB
- Stars: 9
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# h3-proxy
A **proxy event handler** for [h3](https://github.com/unjs/h3), using `proxyRequest`.
- ✨ [Release Notes](./CHANGELOG.md)
# Features
- 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).
- Support logs via **consola**.
- Support **Typescript**.# Installation
```bash
# pnpm
$ pnpm add h3-proxy# yarn
$ yarn add h3-proxy# npm
$ npm i h3-proxy
```# Basic usage
```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
// Define proxy event handler
const proxyEventHandler = createProxyEventHandler({
target: `http://127.0.0.1:${port}`,
pathRewrite: {
'^/api': '',
},
pathFilter: ['/api/**'],
// enableLogger: true
})// Add proxy middlewares
app.use(eventHandler(proxyEventHandler))// Define api routes
app.use(
'/test',
eventHandler(() => 'Hello world!')
)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
## createProxyEventHandler
Create a `h3` event handler that can handle **proxy requests**.
```ts
const proxyEventHandler = createProxyEventHandler({
// options
})
```# Options
| Key | Type | Required | Default value | Description |
| :---: | :---: | :---: | :---: | :---: |
| `target` | `string` | `true` | `undefined` | Proxy target address, including **protocol**, **host** and **port**. url string to be parsed with the `node:url` module|
| [pathFilter](https://github.com/yisibell/h3-proxy#pathFilter) | `string, string[], glob, glob[], Function` | `false` | `undefined` |Narrow down which requests should be proxied. |
| [pathRewrite](https://github.com/yisibell/h3-proxy#pathRewrite) | `object/Function` | `false` | `undefined` | Rewrite target's url path. Object-keys will be used as RegExp to match paths. |
| [configureProxyRequest](https://github.com/yisibell/h3-proxy#configureProxyRequest) | `Function` | `false` | `undefined` | Configure options of `proxyRequest`. More details see [built-in util proxyRequest of h3](https://github.com/unjs/h3) |
| `proxyRequestMethod`
(Added in **v1.13.0**) | `Function` | `false` | `undefined` | Customize `proxyRequest` of **h3** method. |
| `enableLogger` | `boolean` | `false` | `true` | Whether to enable logger which is created by **consola**. |
| `loggerOptions` | `ConsolaOptions` | `false` | `{}` | Configure the options of [consola](https://github.com/unjs/consola). |
| `changeOrigin` | `boolean` | `false` | `false` | Whether to changes the origin of the host header to the target URL |## pathFilter
- **path matching**
- `createProxyEventHandler({...})` - matches any path, all requests will be proxied when `pathFilter` is not configured.
- `createProxyEventHandler({ pathFilter: '/api', ...})` - matches paths starting with `/api`- **multiple path matching**
- `createProxyEventHandler({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})`
- **wildcard path matching**
For fine-grained control you can use wildcard matching. Glob pattern matching is done by _micromatch_. Visit [micromatch](https://www.npmjs.com/package/micromatch) or [glob](https://www.npmjs.com/package/glob) for more globbing examples.
- `createProxyEventHandler({ pathFilter: '**', ...})` matches any path, all requests will be proxied.
- `createProxyEventHandler({ pathFilter: '**/*.html', ...})` matches any path which ends with `.html`
- `createProxyEventHandler({ pathFilter: '/*.html', ...})` matches paths directly under path-absolute
- `createProxyEventHandler({ pathFilter: '/api/**/*.html', ...})` matches requests ending with `.html` in the path of `/api`
- `createProxyEventHandler({ pathFilter: ['/api/**', '/ajax/**'], ...})` combine multiple patterns
- `createProxyEventHandler({ pathFilter: ['/api/**', '!**/bad.json'], ...})` exclusion> :warning: TIPS, In multiple path matching, you cannot use string paths and wildcard paths together.
- **custom matching**
For full control you can provide a custom function to determine which requests should be proxied or not.
```js
/**
* @return {Boolean}
*/
const pathFilter = function (path, req) {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';
};const apiProxy = createProxyEventHandler({
target: 'http://www.example.org',
pathFilter: pathFilter,
});
```## pathRewrite
Rewrite target's url path. **Object-keys** will be used as **RegExp** to match paths.
```js
// rewrite path
pathRewrite: {'^/old/api' : '/new/api'}// remove path
pathRewrite: {'^/remove/api' : ''}// add base path
pathRewrite: {'^/' : '/basepath/'}// custom rewriting
pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }// custom rewriting, returning Promise
pathRewrite: async function (path, req) {
const should_add_something = await httpRequestToDecideSomething(path);
if (should_add_something) path += "something";
return path;
}
```## configureProxyRequest
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
createProxyEventHandler({
// ...
// the param `event` is H3Event
configureProxyRequest(event) {
// return your custom options of proxyRequest// eg: specify some request headers
// return {
// headers: {}
// }return {}
}
})
```# Framework Supports
## Nuxt- using [nuxt-proxy-request](https://github.com/yisibell/nuxt-proxy-request) module.
- using `h3-proxy` directly in **Nuxt**.Add a [server middleware](https://nuxt.com/docs/guide/directory-structure/server#server-middleware).
```ts
// ~/server/middleware/proxy.tsimport { createProxyEventHandler } from 'h3-proxy'
export default defineEventHandler(createProxyEventHandler({
// options...
}))
```