Activité 00 – Solution possible

Ce qui suit est une solution possible pour Activité 00 (si votre solution est différente, ça ne veut pas dire qu'elle est mauvaise!). J'ai suivi le modèle général proposé par ../../../Sources/service-REST-JavaScript-sans-cadriciel.html et je n'ai pas fait toutes les validations demandées.

Fichier serveur.js

Je n'ai pas fait de changement à ce fichier si on le compare à celui présenté dans ../../../Sources/service-REST-JavaScript-sans-cadriciel.html. Le voici à titre de rappel :

const http = require('http');
const hostname = '127.0.0.1';
const port = 8421; // mettons
const server = require('./route.js'); // importer les routes
server.listen(port, hostname, () => {
   console.log('Serveur en exécution sur http://' + hostname + ':' + port + '/');
});

Fichier route.js

Mon fichier route.js va comme suit. Les explications ont été données en classe.

const http = require('http');
const url = require('url');
const queryString = require('query-string');

function estEntier(n) {
  if (isNaN(n)) {
    return false;
  }
  const x = parseFloat(n);
  return (x | 0) === x;
}

function urlInvalide(req, res) {
  const mathsOps = require('./controller.js');
  console.log('Request type: ' + req.method + ' Endpoint: ' + req.url);
  mathsOps.invalidUrl(req, res);
}

function unaryOp(req,res,f,n) {
  if(!estEntier(n))
    urlInvalide(req, res);
  else
    f(req, res, new Number(n));
}

function binaryOp(req, res, f, x, y) {
   f(req, res, new Number(x), new Number(y));
}

// à titre d'illustration seulement (préférez unOps)
function createUnOps() {
  const mathsOps = require('./controller.js');
  const unOps = {};
  unOps['!'] = mathsOps.opFactorielle;
  unOps['p'] = mathsOps.opEstPremier;
  unOps['np'] = mathsOps.opNièmePremier;
  return unOps;
}

const binOps = (() => {
  const mathsOps = require('./controller.js');
  const binOps = {};
  binOps['.'] = mathsOps.opSomme;
  binOps['-'] = mathsOps.opDifférence;
  binOps['*'] = mathsOps.opProduit;
  binOps['/'] = mathsOps.opQuotient;
  binOps['%'] = mathsOps.opReste;
  return binOps;
})();

const unOps = (() => {
  const mathsOps = require('./controller.js');
  const unOps = {};
  unOps['!'] = mathsOps.opFactorielle;
  unOps['p'] = mathsOps.opEstPremier;
  unOps['np'] = mathsOps.opNièmePremier;
  return unOps;
})();

module.exports = http.createServer((req, res) => {
  const mathsOps = require('./controller.js');
  const reqUrl =  url.parse(req.url, true);

  if(reqUrl.pathname == '/math' && req.method === 'GET') {
    console.log('Request type: ' + req.method + ' Endpoint: ' + req.url);
    const parsed = queryString.parseUrl(req.url);
    const op = parsed.query.op;
    if(op in binOps) {
      const x = parsed.query.x;
      const y = parsed.query.y;
      binaryOp(req, res, binOps[op], x, y);
    } else if (op in unOps) {
      const n = parsed.query.n;
      unaryOp(req, res, unOps[op], n);
    } else {
      urlInvalide(req, res);
    }
  } else {
    urlInvalide(req, res);
  }
})

Fichier controller.js

Mon fichier controller.js va comme suit. Les explications ont été données en classe.

const url = require('url');

function somme(x,y) {
   return x + y;
}
function différence(x,y) {
   return x - y;
}
function produit(x,y) {
   return x * y;
}
function quotient(x,y) {
   return x / y;
}
function reste(x,y) {
   return x % y;
}
function factorielle(n) {
   return n == 0? 1 : n * factorielle(n-1);
}
function estPremier(n) {
   if(n < 2) return false;
   const seuil = Math.sqrt(n);
   for(let i = 2; i <= seuil; ++i)
      if(reste(n, i) == 0)
         return false;
   return true;
}
function nièmePremier(n) {
   let cpt = 0;
   let i = 2;
   while(cpt <= n) {
      if(estPremier(i)) {
         ++cpt;
         if(cpt == n) break;
      }
      ++i;
   }
   return i;
}


function makeResponse(req, res, payload) {
  const reqUrl = url.parse(req.url, true)
  res.statusCode = 200;
  res.setHeader('content-Type', 'Application/json');
  res.end(JSON.stringify(payload))
}

exports.opSomme = function(req, res, x, y) {
  makeResponse(req, res, {
    "opération": "somme",
    "x": x,
    "y": y,
    "résultat": somme(x,y)
  });
}

exports.opDifférence = function(req, res, x, y) {
  makeResponse(req, res, {
    "opération": "différence",
    "x": x,
    "y": y,
    "résultat": différence(x,y)
  });
}

exports.opProduit = function(req, res, x, y) {
  makeResponse(req, res, {
    "opération": "produit",
    "x": x,
    "y": y,
    "résultat": produit(x,y)
  });
}

exports.opQuotient = function(req, res, x, y) {
  makeResponse(req, res, {
    "opération": "quotient",
    "x": x,
    "y": y,
    "résultat": quotient(x,y)
  });
}

exports.opReste = function(req, res, x, y) {
  makeResponse(req, res, {
    "opération": "reste",
    "x": x,
    "y": y,
    "résultat": reste(x,y)
  });
}

exports.opFactorielle = function(req, res, n) {
  makeResponse(req, res, {
    "opération": "factorielle",
    "n": n,
    "résultat": factorielle(n)
  });
}

exports.opEstPremier = function(req, res, n) {
  makeResponse(req, res, {
    "opération": "estPremier",
    "n": n,
    "résultat": estPremier(n)
  });
}

exports.opNièmePremier = function(req, res, n) {
  makeResponse(req, res, {
    "opération": "nièmePremier",
    "n": n,
    "résultat": nièmePremier(n)
  });
}

exports.invalidUrl = function(req, res) {
   var response = [
     {
       "message": "Endpoint incorrect. Les options possibles sont "
     },
     availableEndpoints
   ]
   res.statusCode = 404;
   res.setHeader('content-Type', 'Application/json');
   res.end(JSON.stringify(response))
}
 
const availableEndpoints = [
  {
    method: "GET",
    getCours: "/math"
  }
]

Voilà!


Valid XHTML 1.0 Transitional

CSS Valide !