npm package: @strata-js/rpcbridge
Description: Strata.js RPC Bridge Server
Author: Christopher S. Case
Latest version: 2.1.0

# Strata WebSocket RPC Bridge Server
A server that exposes [Strata Services](https://gitlab.com/stratajs/strata) over HTTP and WebSockets.

## Installation

This package is published via NPM's npm repository.

```bash
// npm
$ npm add @strata-js/rpcbridge

// yarn
$ yarn add @strata-js/rpcbridge
```

## Usage (Using the server by itself)

```typescript
import { RPCBridgeServer } from '@strata-js/rpcbridge';

const serverConfig = {
    server: {
        // Enable HTTP Endpoint
        enableHTTP: true,
        // Enable WebSocket Endpoint
        enableWS: true,
        // Port for the server to listen on
        port: 1337,
        // This applies to both HTTP and WS endpoints.
        path: '/api',
        // Exclude stack trace when returning errors.
        excludeStack: false,
        // Allow callers to override the configured service queue name.
        allowQueueNameOverride: false,
    },
    strata: {
        redis: {
            host: 'localhost',
            port: 6379
        },
        client: {
            name: 'RPCServer'
        },
        queues: {
            deleteOnAck: true
        }
    },
    globalBlockList: [ 'service:*' ],
    services: {
        example: {
            queue: 'Requests:StrataExample',
            blockList: [ 'test:fail' ]
        },
        other: {
            queue: 'Requests:StrataExampleOther',
            allowList: [ 'test:*' ]
        },
    }
}

const rpcServer = new RPCBridgeServer(serverConfig);
rpcServer.startListening();
```

## Usage (Bring your own Socket.IO and Express Server)

```typescript
import fs from 'fs';
import { RPCBridgeServer } from '@strata-js/rpcbridge';
import http from 'http';
import express from 'express';
import { Server as SIOServer } from 'socket.io';

const app = express();
const server = http.createServer(app);
const io = new SIOServer(server);

app.get('/test', (_req, res) =>
{
    res.send('Hello World!');
});

const serverConfig = fs.readFileSync('/path/to/config.json');
new RPCBridgeServer(serverConfig, {}, { expressApp: app, httpServer: server, ioServer: io });

server.listen(serverConfig.server.port);
```

## Block and Allow Lists
Each service can be configured with a block and allow list. This is an array of strings that follow a pattern of
`context:operation`, or a global set of operations for a context can be set by using `context:*`. There is also a 
`globalBlockList` property that applies to every service. 

The `globalBlockList` is always evaluated first. The `allowList` and `blockLists` are mutually exclusive with the 
`allowList` taking precedence, as such the `blockList` will be ignored if an `allowList` is defined for a service.  

## Using the service endpoints.

If the HTTP endpoint is active it can be used by using an HTTP `POST` request with a body like so:
```
{
    "serviceName" : "name",
    "context" : "example",
    "operation" : "test",
    "payload" : { "value" : 1 }
}
```

If you would like ot use the WebSocket endpoint please see the 
[Starta RPC Client](https://gitlab.com/strata-js/tools/strata-rpcbridge-client) library.


## Using Middleware
When constructing an instance of the RPCBridge, you can pass in middle ware to the HTTP and Websocket endpoints like so.

```typescript
function HTTPLog (req, _res, next)
{
    console.log('Got Request', req.body);
    next();
}

function HTTPSetAuthInfo (req, _res, next)
{
    req.body.auth = 'secretID';
    next();
}

function WSLog (_socket, req, next)
{
    console.log('Got Request', req);
    next();
}

function WSSetAuthInfo (_socket, req, next)
{
    req.auth = 'secretID';
    next();
}

new RPCBridgeServer(
    serverConfig,
    {http:[HTTPLog, HTTPSetAuthInfo], socket: [WSLog, WSSetAuthInfo]}
);

server.listen(serverConfig.server.port);
```

#### Future Improvements
* More granular control when bringing your own HTTP Server