在不使用'bind'的情况下公开JSON-RPC中的类方法

时间:2019-07-15 08:27:52

标签: node.js bind json-rpc

我正在使用nodeJS创建一个JSON-RPC API。这个API必须管理一个postgreSQL(带有仓库)。 我正在使用pg-promise来管理数据库,与此相关的post我必须在我的仓库中使用类。

每个存储库都有一个this.expose属性,其中包含其公开的方法。我的问题是我必须调用bind(this),否则当服务器调用该方法时,它不是类上下文(例如,在insertOne中,它不是DevicesRepository,而是./db/中的“ methods” var)索引/ js)。 我认为这是因为在此文件中,我使用了“ Object.assign”。 我是否必须使用“ Object.assign”或是否存在“连接”并公开这些方法的其他方法? 我试过了,但是不能与我的服务器一起使用。如果我在./db/index.js中这样声明methods对象

const methods = [
    db.systems.expose,
    db.devices.expose
];

这将导出类似对象

methods = [
  {
    'systems.insert': [Function: bound insertOne],
    'systems.getById': [Function: bound getOne]
  },
  {
    'devices.insert': [Function: bound insertOne],
    'devices.getById': [Function: bound getOne]
  }
]

在我做服务器时,它需要一个像这样的对象:

methods = {
  'systems.insert': [Function: bound insertOne],
  'systems.getById': [Function: bound getOne],
  'devices.insert': [Function: bound insertOne],
  'devices.getById': [Function: bound getOne]
}

P.S:具有相同名称的函数可以存在于多个回购中(例如上面的“ insertOne”和“ getOne”)

一些代码 服务器

const http = require('http');
const Database = require('../db');
const methods = Database.methods;

const requestHandler = (req, res) => {
  const body = [];
  req.on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    /* shortened for brevity */
    const bodyStr = Buffer.concat(body).toString();
    res.setHeader('Content-Type', 'application/json');

    // parse body en JSON
    let request = JSON.parse(bodyStr);

    requestProcessor(request).then((response) => {
      sendResponse(res, response);
    });
  });
}

async function requestProcessor(request) {
  /* shortened for brevity */
  try {
    response.result = await Promise.resolve(methods[request.method](request.params));
    if (!response.id) {
      response = undefined; // don't return a response if id is null
    }
  } catch (err) { /* some stuff */ }

  return response;
}
/* hidden for brevity */

db / index.js

'use strict';

const repos = require('./repos'); // ./repos/index.js
const config = require('./conf');


// pg-promise initialization options:
const initOptions = { /* hidden for brevity */ };

const pgp = require('pg-promise')(initOptions);
const db = pgp(config);

const methods = Object.assign({},
    db.systems.expose,
    db.devices.expose,
);

module.exports = {
  methods
}

db / repos / index.js

'use strict';

module.exports = {
  Systems: require('./systems'),
  Devices: require('./devices'),
};

其中一个仓库

'use strict';

/* shortened for brevity */

class DevicesRepository {
  constructor(db, pgp) {
    this.expose = {
      'devices.insert': this.insertOne.bind(this),
      // other method exposition
    }
  }

  insertOne(params) {
    // if I use 'bind(this)', this = DevicesRepository
    // if I don't use 'bind(this)', this = 'methods object' in db/index.js
    /* hidden for brevity */
  }
}

module.exports = DevicesRepository

0 个答案:

没有答案