Bonjour!

(désolé pour ce long post, merci d'avance à ceux qui le liront )
Pour m'améliorer en JS (notamment sur les Promises et async/await) je veux faire une API JSON RPC qui doit pouvoir répondre et tenir le coup face à un gros trafic, en gérant une base de données PostgreSQL.
J'utilise http et pg-promise.
Pour faire l'API avec http je me suis (très fortement) inspiré de http-jsonrpc-server qui me convenait tout à fait à quelques détails.
J'ai un peu de mal avec les promesses | async/await (que je considère quand même comme une des base...), et souhaiterai avoir des avis sur ce que j'ai fait.

  1. chacun des "sous-fichiers" de gestion de la DB (par exemple roles.js) exporte l'objet "methods" qui contient toutes ses fonctions accessibles sur l'API.
  2. database.js crée la connexion à la DB et importe les "sous-fichier de gestion". Ce module exporte son objet "methods" qui regroupe simplement tous les objets "methods" des sous-fichiers.
  3. server.js crée le serveur et définie les "methods" de l'API en utilisant database.methods. Il a un handler de requête qui les check etc avant de lancer la fonction (checks cachés ici)


En gros dans server.js : methods = concaténation de l'objet "methods" de tous les "sous-fichiers", par exemple ici methods.InsertRoles(values);
Le handler de requête "requestHandler" appelle "processRequest" qui est une fonction asynchrone, cette derniere doit lancer la fonction demandée dans la requête (avec les params).

Les points sur lesquels je voudrais un avis :

Promise & async/await :
  1. "processRequest" est asynchrone
  2. elle appelle la méthode souhaitée (par exemple InsertRoles) dans un await Promise.resolve
  3. InsertRoles retourne les résultat de l'insertion en base avec un (la méthode de pg-promise utilisée dedans retourne une Promise)


Peut-être question bête mais : dans quels cas de figure j'aurai besoin de déclarer cette méthode comme "async" ?

"Initialisation" des sous-fichiers
Dans mon code database.js crée la connexion à la base et je souhaite que ce soit la même pour toute l'API : une seule instance, pas une par fichier (est-ce une bonne idée ?)
Mes "sous-fichiers" ont besoins de clle-ci pour fonctionner (query etc) donc pour leur passer j'ai dut faire une fonction Init qui stock la variable, est-ce qu'il y a un moyen de faire ceci sans utiliser cette fonction ? Par exemple
Code JAVASCRIPT : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
// database.js
const pgp = require('pg-promise')();
const db = pgp(conf);
const roles = require('./schema/roles')(db);

Merci d'avance !

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
const http = require('http');
 
const path = '/api/v1',
			port = 9000;
 
const db = require('./db/database');
 
const methods = db.methods;
 
const requestHandler = (req, res) => {
  /**
   * check authentification, requete valide, ...
   * hidden for brevity
   */
 
  // lecture requete
  const body = [];
  req.on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    // on recupere le body pour savoir quoi faire
    const bodyStr = Buffer.concat(body).toString();
    let request;
    try {
      request = JSON.parse(bodyStr);
    } catch (err) {
      // hidden for brevity
    }
 
    // quelques autres checks
    res.setHeader('Content-Type', 'application/json');
 
    // lance la fonction demander
    processRequest(request).then((response) => {
      console.log(`requestHandler.response=${JSON.stringify(response)}`);
      sendResponse(res, response); // renvoies les datas
    });
  });
}
 
async function processRequest(request) {
  let response = { jsonrpc: '2.0' };
 
  try {
    response.result = await Promise.resolve(methods[request.method](request.params));
    console.log(`processRequest.response=${JSON.stringify(response.result)}`);
  } catch (err) {
    // response contient response.error
  }
 
  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}`)
})

database.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
const pgp = require('pg-promise')();
const conf = require('./conf.json');
 
const db = pgp(conf);
 
const roles = require('./schema/roles');
 
roles.Init(db);
 
const methods = roles.methods;
 
const Collections = {
	ColumnSets: {
		Role: new pgp.helpers.ColumnSet(['name'], {table: 'roles'})
	}
}
 
module.exports = {
	Collections,
	methods
}

role.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
const pgp = require('pg-promise')();
 
var Database = null;
const cs = new pgp.helpers.ColumnSet(['name'], {table: 'roles'});
 
exports.Init = function(db){
  Database = db;
}
 
exports.methods = {
  InsertRoles: function (values) {
    var query = pgp.helpers.insert(values, cs);
 
    if(values.returnData) query += " RETURNING roleId, name";
 
    return Database.any(query)
      .then(data => {
        console.log(`roles.response=${JSON.stringify(data)}`);
        return data;
      });
  }
}