{"id":18690,"library":"protomux-rpc-router","title":"Protomux RPC Router","description":"Protomux RPC Router v1.2.0 wraps protomux-rpc responders with an onion-style middleware stack for HyperDHT servers, enabling composable global and per-method middleware (logging, auth, rate limiting). It integrates with HyperDHT connections and uses compact-encoding for request/response. Alternative to manual middleware wiring in protomux-rpc, with a predictable nested invocation order. Currently maintained, with monthly releases.","status":"active","version":"1.2.0","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/holepunchto/protomux-rpc-router","tags":["javascript"],"install":[{"cmd":"npm install protomux-rpc-router","lang":"bash","label":"npm"},{"cmd":"yarn add protomux-rpc-router","lang":"bash","label":"yarn"},{"cmd":"pnpm add protomux-rpc-router","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Underlying RPC implementation; the router wraps protomux-rpc's respond() method.","package":"protomux-rpc","optional":false},{"reason":"Used for encoding/decoding request and response values in method registration.","package":"compact-encoding","optional":false},{"reason":"Transport layer for multiplexing connections; used indirectly via protomux-rpc.","package":"protomux","optional":true},{"reason":"Optional capability verification for method access control.","package":"hyperswarm-capability","optional":true}],"imports":[{"note":"Package exports ESM default export. CommonJS require will not work without a wrapper.","wrong":"const ProtomuxRpcRouter = require('protomux-rpc-router')","symbol":"ProtomuxRpcRouter","correct":"import ProtomuxRpcRouter from 'protomux-rpc-router'"},{"note":"Use 'import type' for type-only imports in TypeScript to avoid runtime errors.","wrong":"","symbol":"ProtomuxRpcRouter (type import)","correct":"import type ProtomuxRpcRouter from 'protomux-rpc-router'"},{"note":"The Middleware type is exported for TypeScript users to define middleware objects.","wrong":"","symbol":"Middleware interface","correct":"import type { Middleware } from 'protomux-rpc-router'"}],"quickstart":{"code":"import ProtomuxRpcRouter from 'protomux-rpc-router'\nimport c from 'compact-encoding'\n\n// Create router with optional capability\nconst router = new ProtomuxRpcRouter({ capability: process.env.CAPABILITY_KEY ? Buffer.from(process.env.CAPABILITY_KEY, 'hex') : undefined })\n\n// Add global middleware (logging example)\nrouter.use({\n  onrequest: async (ctx, next) => {\n    console.log('Request:', ctx.method)\n    const res = await next()\n    console.log('Response:', res)\n    return res\n  },\n  onopen: async () => { console.log('Router started') },\n  onclose: async () => { console.log('Router stopped') }\n})\n\n// Register a method\nconst add = router.method('add', {\n  requestEncoding: c.json,\n  responseEncoding: c.json\n}, async (req) => {\n  return { result: req.a + req.b }\n})\n\n// Add per-method middleware (validation example)\nadd.use({\n  onrequest: async (ctx, next) => {\n    if (typeof ctx.value.a !== 'number' || typeof ctx.value.b !== 'number') {\n      throw new Error('Invalid input')\n    }\n    return next()\n  }\n})\n\n// Simulate a connection (in practice, from HyperDHT)\nconst fakeConnection = {\n  publicKey: Buffer.from('somekey'),\n  open: () => {},\n  close: () => {}\n}\nrouter.handleConnection(fakeConnection)\nawait router.ready()\n// ... later\nawait router.close()","lang":"typescript","description":"Creates a ProtomuxRpcRouter, adds global logging middleware, registers an 'add' method with per-method validation, and attaches to a connection."},"warnings":[{"fix":"Use an object with `onrequest` method instead of a plain function.","message":"Middleware must be objects with `onrequest` method; using a function directly will fail.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure each method name is unique when calling `router.method()`.","message":"Method names must be unique; registering a duplicate name will not throw but will overwrite the previous registration.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Provide an explicit `protomuxRpcId` Buffer or ensure `connection.publicKey` is set.","message":"The `protomuxRpcId` parameter in `handleConnection` defaults to `connection.publicKey`; if that property is undefined or not a Buffer, unexpected behavior may occur.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always return the result of `await next()` or a custom value from middleware.","message":"Middleware `onrequest` must return a value that propagates as the response; returning nothing will result in `undefined` response to the caller.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"","message":"No deprecated features in current version.","severity":"deprecated","affected_versions":""}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Use `import ProtomuxRpcRouter from 'protomux-rpc-router'` in an ESM context.","cause":"Using CommonJS require on an ESM-only package.","error":"ProtomuxRpcRouter is not a constructor"},{"fix":"Run `npm install protomux-rpc-router` and check for spelling errors.","cause":"Package not installed or typo in package name.","error":"Cannot find module 'protomux-rpc-router'"},{"fix":"Ensure middleware is an object with an async `onrequest(ctx, next)` function.","cause":"Middleware object does not have an `onrequest` method.","error":"TypeError: middleware.onrequest is not a function"},{"fix":"Specify `requestEncoding` in method options (e.g., `c.json` from compact-encoding).","cause":"No request encoding provided when registering method, or the received request data is not decoded.","error":"ctx.value is undefined"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}