Skip to content

jamesvillarrubia/feathers-rpc

Repository files navigation

feathers-rpc

NPM

npm

GitHub Workflow Status

Libraries.io dependency status for latest release

This library is a FeathersJS middleware to allow simple Remote Procedure Calls (RPCs) to interact with Feathers Services and custom methods.

To function, this middleware takes an RPC verb from between the end of a path behind a colon (e.g. /messages:callMySpecialMethod) and then appends callMySpecialMethod as a parameter in the Feathers context as well as overwriting the x-service-method header. This allows a custom method to be trigerred within the /messages service without requiring modification of headers directly, which can be disabled in some webhook and integration tools.

Installation

npm install --save feathers-rpc

Then add the library to your middleware:

//app.js
const parseRpcVerb = require('feathers-rpc');

//...

app.use(express.urlencoded({ extended: true }));
app.use(parseRpcVerb());                          //<--------
app.configure(express.rest());

service(options)

Options:

  • disableHeader (optional, default: false) - Set to true to prevent the x-service-method header from being overwritten by the middleware. The RPC verb can still get captured and used from the Feathers hook ctx object.
  • allowedRpcVerbs (optional. default: any) - Accepts a string or an array of strings. Defaults to fully open, allowing any verb. Setting to [] will disallow any verb. In order to use the x-service-method automatic call, the custom method of the service must be named exactly the same as the verb sent.

Example Service

//app.js

class MessageService {
  async find (params) { return { data: 'find', params }; }
  async create (data, params) { return { data: 'create', params }; }
  async callRpcMethod (data, params) { return { data: 'rpc', params }; }
}

const app = feathers()
  .configure(rest())
  .use('/messages', new MessageService(), {
    methods: ['find', 'create', 'callRpcMethod']
  });

Then to hit this service you can follow the instructions here

The following two curl requests are then basically equivalent:

curl -H "Content-Type: application/json" \
  -H "x-service-method: callRpcMethod" \
  -X POST -d '{"message": "Hello world"}' \ 
  http://localhost:3030/messages

curl -H "Content-Type: application/json" \
  -X POST -d '{"message": "Hello world"}' \ 
  http://localhost:3030/messages:callRpcMethod

Using Verbs with ID

Because the middleware doesn't know available routes or nesting, it cannot distinguish between messages:verb and messages/1:verb. In order to pass a specific ID to your custom function, include it in the data { id: 1 } or in the query messages:verb?id=1; This will allow you to fetch that entity and still use the custom methods.

Extending an existing Service

You can easily add a custom method to any service and use the RPC middleware. For example, if I was extending a Knex/SQL based service generated from the CLI, I would modify it like so:

export class MessagesService extends KnexService {
   async callRpcMethod(data, params){
      //... do fancy stuff
    }
}

Compatability

This library is tested against REST APIs for Feathers v4 and v5. This library also supports Koa on v5. Since the x-service-method header functionality does not exist in v4, the RPC verb can be extracted inside a hook context or params with the property params.rpcVerb. You can then redirect to a separate function directly.

Additional testing and PRs are welcome.

feathers v5 v4 v3
express
koa
primus

Contributing

Please see https://github.com/jamesvillarrubia/feathers-rpc/blob/main/.github/contributing.md

Credit

Inspired by work by Ben Zelinski.