# json-rpc-engine

> A tool for processing JSON-RPC messages.

Latest version **6.1.0** (published 2020-11-20) · ISC license · 0 weekly downloads

## Install

```sh
npm install json-rpc-engine
pnpm add json-rpc-engine
yarn add json-rpc-engine
bun add json-rpc-engine
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 6.1.0 |
| Published | 2020-11-20 |
| First published | 2016-09-29 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=10.0.0 |
| Dependencies | 2 |
| Unpacked size | 46.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 160 |
| Author | kumavis |
| Maintainers | gudahtt, metamaskbot, estebanmino, rekmarks, danfinlay, kumavis |

## Links

- npm: https://www.npmjs.com/package/json-rpc-engine
- Repository: https://github.com/MetaMask/json-rpc-engine
- Homepage: https://github.com/MetaMask/json-rpc-engine#readme
- Issues: https://github.com/MetaMask/json-rpc-engine/issues
- npm.io page: https://npm.io/package/json-rpc-engine

## Dependencies (2)

- [eth-rpc-errors](https://npm.io/package/eth-rpc-errors.md) ^4.0.2
- [@metamask/safe-event-emitter](https://npm.io/package/@metamask/safe-event-emitter.md) ^2.0.0

## Recent versions

- 6.1.0 (latest) — 2020-11-20
- 6.0.0 — 2020-11-19
- 5.4.0 — 2020-11-09
- 5.3.0 — 2020-07-30
- 5.2.0 — 2020-07-28
- 5.1.8 — 2020-02-10
- 5.1.6 — 2020-01-08
- 5.1.5 — 2019-11-08
- 5.1.4 — 2019-09-18
- 5.1.3 — 2019-08-20
- 5.1.1 — 2019-06-25
- 5.1.0 — 2019-06-25
- 5.0.0 — 2019-03-11
- 4.0.0 — 2018-12-10
- 3.8.0 — 2018-10-04
- … 21 more at https://npm.io/package/json-rpc-engine/versions

## README

# json-rpc-engine

A tool for processing JSON-RPC requests and responses.

## Usage

```js
const { JsonRpcEngine } = require('json-rpc-engine')

let engine = new JsonRpcEngine()
```

Build a stack of JSON-RPC processors by pushing middleware to the engine.

```js
engine.push(function(req, res, next, end){
  res.result = 42
  end()
})
```

Requests are handled asynchronously, stepping down the stack until complete.

```js
let request = { id: 1, jsonrpc: '2.0', method: 'hello' }

engine.handle(request, function(err, response){
  // Do something with response.result, or handle response.error
})

// There is also a Promise signature
const response = await engine.handle(request)
```

Middleware have direct access to the request and response objects.
They can let processing continue down the stack with `next()`, or complete the request with `end()`.

```js
engine.push(function(req, res, next, end){
  if (req.skipCache) return next()
  res.result = getResultFromCache(req)
  end()
})
```

By passing a _return handler_ to the `next` function, you can get a peek at the result before it returns.

```js
engine.push(function(req, res, next, end){
  next(function(cb){
    insertIntoCache(res, cb)
  })
})
```

Engines can be nested by converting them to middleware using `JsonRpcEngine.asMiddleware()`:

```js
const engine = new JsonRpcEngine()
const subengine = new JsonRpcEngine()
engine.push(subengine.asMiddleware())
```

### `async` Middleware

If you require your middleware function to be `async`, use `createAsyncMiddleware`:

```js
const { createAsyncMiddleware } = require('json-rpc-engine')

let engine = new RpcEngine()
engine.push(createAsyncMiddleware(async (req, res, next) => {
  res.result = 42
  next()
}))
```

`async` middleware do not take an `end` callback.
Instead, the request ends if the middleware returns without calling `next()`:

```js
engine.push(createAsyncMiddleware(async (req, res, next) => {
  res.result = 42
  /* The request will end when this returns */
}))
```

The `next` callback of `async` middleware also don't take return handlers.
Instead, you can `await next()`.
When the execution of the middleware resumes, you can work with the response again.

```js
engine.push(createAsyncMiddleware(async (req, res, next) => {
  res.result = 42
  await next()
  /* Your return handler logic goes here */
  addToMetrics(res)
}))
```

You can freely mix callback-based and `async` middleware:

```js
engine.push(function(req, res, next, end){
  if (!isCached(req)) {
    return next((cb) => {
      insertIntoCache(res, cb)
    })
  }
  res.result = getResultFromCache(req)
  end()
})

engine.push(createAsyncMiddleware(async (req, res, next) => {
  res.result = 42
  await next()
  addToMetrics(res)
}))
```

### Gotchas

Handle errors via `end(err)`, *NOT* `next(err)`.

```js
/* INCORRECT */
engine.push(function(req, res, next, end){
  next(new Error())
})

/* CORRECT */
engine.push(function(req, res, next, end){
  end(new Error())
})
```

However, `next()` will detect errors on the response object, and cause
`end(res.error)` to be called.

```js
engine.push(function(req, res, next, end){
  res.error = new Error()
  next() /* This will cause end(res.error) to be called. */
})
```

---
_Source: https://npm.io/package/json-rpc-engine · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
