JSONRPC API: круговой объект = плохая архитектура? - PullRequest
0 голосов
/ 02 июля 2019
  • Элемент списка

Мне нужно создать JSON RPC API, который должен управлять базой данных Postgre.Мое приложение состоит из сервера и базы данных с репозиториями.

Методы, которые предоставляются, являются следствием свойства «Methods» каждого репо.

Моя проблема в том, что (я думаю) яЯ не использовал хорошую архитектуру, потому что у меня есть круговой объект в каждом репо: в каждом репо свойство 'db' включает все репо (включая его самого).Например: DevicesRepository.db = - все функции pg-обещания - все остальные репозитории (RolesRepository, ShellsRepository ...) - DevicesRepository (DevicesRepository) Это проблема?Я думаю, это означает, что у меня плохая архитектура?

У меня также есть проблема с 'this' в репо, я открою другой вопрос, если это не та же проблема

Какмой API работает:

  1. . / server / server.js получить методы из ./db/index.js
  2. . / db / index.js 'regroup' все repo.methodsв одном объекте с «Object.assign ()»
  3. в каждом репо я должен связать «this» (пример = DevicesRepository), иначе методы (здесь «add») не знают, что это this.db)
  4. потому что я связываю контекст с методом this.db, но в вызове tx контекст this.db, поэтому я больше не могу использовать this.Collections

. / Db / repos / devices.js

'use strict';

class DevicesRepository {
  constructor(db, pgp) {
    this.db = db;
    this.pgp = pgp;

    this.Collections = createColumnsets(pgp);

    this.methods = {
        'devices.insert': this.add.bind(this),
    }
  }

  async add(params) {
    console.log(this); //here this = DevicesRepository
    var device = params.data.device;

    return this.db.tx(function* (transaction) {
      console.log(this); // here this = transaction = DevicesRepository.db

      const system = yield transaction.systems.add(params);
      device.systemid = system.systemId;

      const query = this.pgp.helpers.insert(device, this.Collections.insert);  // this.pgp = undefined
      if(params.return) query += " RETURNING *";

      return transaction.one(query);
    })
    .then(data => {
      // hidden
    })
    .catch(ex => {
      // hidden
    });
  }
}

/* hidden for brevity */

module.exports = DevicesRepository;

. / Db / repos / index.js

'use strict';

module.exports = {
    // other repo are required with the same way
  Devices: require('./devices'),
};

. / Db / index.js

'use strict';

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

// pg-promise initialization options:
const initOptions = {
    //promiseLib: promise, // Use a custom promise library, instead of the default ES6 Promise:
    extend(obj, dc) {
      // other repo are added with the same way
        obj.devices = new repos.Devices(obj, pgp);
    }
};

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

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

module.exports = {
  methods,
}

. / Server / server.js

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

const path = '/api/v1', port = 9000;
const methods = Database.methods;

const requestHandler = (req, res) => {
  //some lines are hidden for brevity
  const body = [];
  req.on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    const bodyStr = Buffer.concat(body).toString();

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

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

async function requestProcessor(request) {
  //some lines are hidden for brevity
  let response = { /* some properties */ };

  try {
    response.result = await Promise.resolve(methods[request.method](request.params)); // call the repo method
  } catch (err) {
    // hidden
  }

  return response;
}

const server = http.createServer(requestHandler);
server.listen(port, (err) => {
  if(err) {
    return Log('something bad happened', err);
  }
  Log(`server is listening on ${port}`);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...