Nella stragrande maggioranza di guide su questo argomento, il database utilizzato è MongoDB. Qua mostriamo come sia possibile realizzare delle API Rest basandoci su database MySQL.

Dipendenze necessarie

Le uniche due dipendenze necessarie per realizzare le nostre API sono express e mysql.

Per l’installazione usiamo il Node Package Manager.

Se non abbiamo inizializzato un progetto lanciamo nella directory di lavoro il comando:

npm init

Settiamo i parametri necessari e lanciamo subito i comandi per scaricare le dipendenze:

npm install express --save
npm install mysql --save

Implementare le API Rest

Per implementare tutte le rotte richieste dall’API, utilizzeremo un unico file server.js che conterrà i seguenti metodi:

Verb URI Action
GET /tableName Recupera tutti i record
GET /tableName/id Recupera un singolo record con l’id specificato
POST /tableName Aggiunge un nuovo record
PUT /tableName/id Aggiorna il record con l’id specificato
DELETE /tableName/id Cancella il record con l’id specificato

Struttura

Includiamo i moduli e creiamo il server http usando express.

var express = require('express'),
    app     = express(),
    mysql   = require('mysql');
app.listen(3000);
console.log('Server in ascolto sulla porta 3000');

Connessione al DB

Configuriamo il database e creiamo la connessione verso MySQL.

var express = require('express'),
    app     = express(),
    mysql   = require('mysql'),
    connectionpool = mysql.createPool({
        host     : 'localhost',
        user     : 'root',
        password : 'password',
        database : 'demo_rest'
    });
app.listen(3000);
console.log('Server in ascolto sulla porta 3000');

In cui host, user, password e database vanno impostati in base al database configurato.

Rotte

L’applicazione avrà bisogno di gestire solamente le 5 rotte viste nella tabella sopra.

var express = require('express'),
    app     = express(),
    mysql   = require('mysql'),
    connectionpool = mysql.createPool({
        host     : 'localhost',
        user     : 'root',
        password : 'password',
        database : 'demo_rest'
    }),
res.setHeader({ 'Content-Type': 'application/json' });
app.get('/:table', function(req,res){});
app.get('/:table/:id', function(req,res){});
app.post('/:table', function(req,res){});
app.put('/:table/:id', function(req,res){});
app.delete('/:table/:id', function(req,res){});
 
app.listen(3000);
console.log('Server in ascolto sulla porta 3000');

Ogni rotta prende come parametro una funzione di callback con gli oggetti di richiesta e risposta.
Come si può notare inoltre, andremo ad usare come contenuto della risposta, oggetti in JSON. Ormai uno standard quando si lavora con API REST.
Andremo anche a impostare una gestione degli errori con risposte in JSON.

Gestione della connessione e degli Errori

Otteniamo una connessione dalla pool. Essa potrebbe raggiungere il limite massimo d’allocazione e scatenare un errore che dev’essere dunque gestito.

var express = require('express'),
    app     = express(),
    mysql   = require('mysql'),
    connectionpool = mysql.createPool({
        host     : 'localhost',
        user     : 'root',
        password : 'secret',
        database : 'rest_demo'
    });
res.setHeader({ 'Content-Type': 'application/json' });
app.get('/:table', function(req,res){
    connectionpool.getConnection(function(err, connection) {
        if (err) {
            console.error('CONNECTION error: ',err);
            res.statusCode = 503;
              res.send({
                result: 'error',
                err:    err.code
            });
        } else {
            // Query sul DB usando la connessione stabilita
        }
    });
});

Quando rileviamo degli errori nella connessione, node.js ne terrà traccia sulla console rispondendo con uno status code 503 – Servizio non disponibile con il codice d’errore del server Mysql.

Interrogare MySQL

Le rotte definite permettono di selezionare la tabella e se richiesto un id, usati per costruire la query e restituire la risposta in JSON.
Nell’esempio sotto mostriamo come vengono restituiti gli ultimi 10 record:

var express = require('express'),
    app     = express(),
    mysql   = require('mysql'),
    connectionpool = mysql.createPool({
        host     : 'localhost',
        user     : 'root',
        password : 'password',
        database : 'demo_rest'
    });
app.get('/:table', function(req,res){
    connectionpool.getConnection(function(err, connection) {
        if (err) {
            console.error('CONNECTION error: ',err);
            res.statusCode = 503;
            res.send({
                result: 'error',
                err:    err.code
            });
        } else {
            connection.query('SELECT * FROM '+req.params.table+' ORDER BY id DESC LIMIT 10', req.params.id, function(err, rows, fields) {
                if (err) {
                    console.error(err);
                    res.statusCode = 500;
                    res.send({
                        result: 'error',
                        err:    err.code
                    });
                }
                res.send({
                    result: 'success',
                    err:    '',
                    fields: fields,
                    json:   rows,
                    length: rows.length
                });
                connection.release();
            });
        }
    });
});
app.get('/:table/:id', function(req,res){});
app.post('/:table', function(req,res){});
app.put('/:table/:id', function(req,res){});
app.delete('/:table/:id', function(req,res){});
app.listen(3000);
console.log('Server in ascolto sulla porta 3000');

Ora non resta che implementare la funzione di callback su ogni rotta, come mostrato nell’esempio sopra.

Gli esempi mostrati non sono adatti in fase di produzione, non è una buona pratica quella di specificare nella chiamata REST il nome della tabella su cui si vuol effettuare l’interrogazione. In ogni caso fornisce una buona base di partenza per implementare il proprio sistema di API.