JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3485
  • Score
    100M100P100Q119387F
  • License MIT

A proxy event handler for h3, using proxyRequest.

Package Exports

  • h3-proxy

Readme


h3-proxy

A proxy event handler for h3, using proxyRequest.

Features

  • Powered by built-in proxyRequest of h3.
  • Support http(s) proxy via some simple configurations.
  • Support logs via consola.
  • Support Typescript.

Installation

# pnpm
$ pnpm add h3-proxy

# yarn
$ yarn add h3-proxy

# npm
$ npm i h3-proxy

Basic usage

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.

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).

const proxyEventHandler = createProxyEventHandler([
  {
    // options
  },
  {
    // other proxy target options
  }
])

APIs

createProxyEventHandler

Create a h3 event handler that can handle proxy requests.

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 string, string[], glob, glob[], Function false undefined Narrow down which requests should be proxied.
pathRewrite object/Function false undefined Rewrite target's url path. Object-keys will be used as RegExp to match paths.
configureProxyRequest Function false undefined Configure options of proxyRequest. More details see built-in util proxyRequest of h3
enableLogger boolean false true Whether to enable logger which is created by consola.
loggerOptions ConsolaOptions false {} Configure the options of 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 or 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

⚠️ 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.

    /**
     * @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.

// 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.

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

Add a server middleware.

// ~/server/middleware/proxy.ts

import { createProxyEventHandler } from 'h3-proxy'

export default defineEventHandler(createProxyEventHandler({
  // options...
}))