Bonjour!
Je dois faire une api json rpc et j'ai deux problèmes:
- un circular object (est-ce vraiment un probleme ?)
- plusieurs classes (des repos) et j'ai des difficulté pour utiliser 'this' dans le repo
Je penses que ces problèmes viennent du fait que j'ai mal architecturer l'appli.. ?
Comment mon serveur fonctionne :
Pour le l'architecture DB je me suis inspiré de pg-promise-demo
- ./server/server.js récupère les méthode exposée dans ./db/index.js
- ./db/index.js 'regroupe' toutes les methods de chaque repo dans une objet avec 'Object.assign()'
- Chaque repo possede une propriete 'methods' qui lui permet d'exposer ses methodes (je dois utiliser bind(this) sinon la méthode ne connait pas les propriétés de la classe)
Mon problème de circular object :
Dans chaque repo j'ai une propriete 'db' qui y est injectée depuis db/index.js je lui ajoute les repos grace a une fonction de pg-promise (lignes 9 à 12) du coup dans cette propriété j'ai :
- toutes les méthodes de pg-promise (logique)
- tous les repos (incluant lui-meme)
Exemple avec DevicesRepository.db :
- pg-promise functions
- les autres repos (RolesRepository, ...)
- DevicesRepository
Mon problème de contexte 'this' :
Dans la fonction 'add', 'this.db' est connu parce que je bind 'this' à la fonction (ligne 15)
Par contre dans le 'this.db.tx', le contexte devient 'this.db', donc par exemple this.Collections n'est plus connu
Je suppose que cela signifie que ces problèmes sont liés et que j'ai mal architecturé l'appli ?
Si oui comment auriez-vous fait ?
Merci d'avance!
Un peu de code :
./db/repos/devices.js
Code JAVASCRIPT : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 'use strict'; const cs = {}; // Reusable ColumnSet objects. var Collections = {}; 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 //insert a System (returning the inserted ID) const system = yield transaction.systems.add(params); device.systemid = system.systemId; const query = this.pgp.helpers.insert(device, this.Collections.insert); if(params.return) query += " RETURNING *"; return transaction.one(query); }) .then(data => { Log(`INSERTED device ${JSON.stringify(data)}`); return data; }) .catch(ex => { throw new Error(ex); }); } } /* hidde, for brevity */ module.exports = DevicesRepository;
./db/repos/index.js
Code JAVASCRIPT : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 'use strict'; module.exports = { // other repo are required with the same way Devices: require('./devices'), };
./db/index.js
Code JAVASCRIPT : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 'use strict'; const repos = require('./repos'); // ./repos/index.js const config = require('./conf'); // pg-promise initialization options: const initOptions = { extend(obj, dc) { obj.roles = new repos.Roles(obj, pgp); obj.shells = new repos.Shells(obj, pgp); obj.systems = new repos.Systems(obj, pgp); obj.devices = new repos.Devices(obj, pgp); } }; // Load and initialize pg-promise: const pgp = require('pg-promise')(initOptions); // Create the database instance: 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
Code JAVASCRIPT : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 const http = require('http'); const Database = require('../db'); // ./db/index.js 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(); let request = JSON.parse(bodyStr); requestProcessor(request).then((response) => { sendResponse(res, response); }); }); } async function requestProcessor(request) { let response = { /* some props */ }; try { response.result = await Promise.resolve(methods[request.method](request.params)); } catch (err) { // hidden for brevity } return response; } const server = http.createServer(requestHandler); server.listen(port, (err) => { if(err) { return console.log(('something bad happened', err); } console.log((`server is listening on ${port}`); })
Partager