Crea un'API REST con Node.js ed Express:connessione di un database
Nel primo tutorial, Comprensione delle API RESTful, abbiamo appreso cos'è l'architettura REST, quali sono i metodi e le risposte delle richieste HTTP e come comprendere un endpoint API RESTful. Nel secondo tutorial, Come configurare un server API Express, abbiamo imparato come creare server con entrambi i nodi http
integrati modulo e il framework Express e come instradare l'app che abbiamo creato a diversi endpoint URL.
Attualmente, utilizziamo dati statici per visualizzare le informazioni sull'utente sotto forma di feed JSON quando l'endpoint API viene colpito con un GET
richiesta. In questo tutorial, configureremo un database MySQL per archiviare tutti i dati, connettersi al database dalla nostra app Node.js e consentire all'API di utilizzare GET
, POST
, PUT
e DELETE
metodi per creare un'API completa.
Installazione
Fino a questo punto, non abbiamo utilizzato un database per archiviare o manipolare alcun dato, quindi ne creeremo uno. Questo tutorial utilizzerà MySQL e, se hai già installato MySQL sul tuo computer, sarai pronto per passare al passaggio successivo.
Se non hai installato MySQL, puoi scaricare MAMP per macOS e Windows, che fornisce un ambiente server e un database locali gratuiti. Una volta scaricato, apri il programma e fai clic su Avvia server per avviare MySQL.
Oltre a configurare MySQL stesso, vorremo che il software GUI visualizzi il database e le tabelle. Per Mac, scarica SequelPro e per Windows scarica SQLyog. Dopo aver scaricato e avviato MySQL, puoi utilizzare SequelPro o SQLyog per connetterti a localhost
con il nome utente root
e password root
sulla porta 3306
.
Una volta che tutto è impostato qui, possiamo passare alla configurazione del database per la nostra API.
Configurazione del database
Nel software di visualizzazione del database, aggiungi un nuovo database e chiamalo api
. Assicurati che MySQL sia in esecuzione o non sarai in grado di connetterti a localhost
.
Quando hai l'api
database creato, spostati in esso ed esegui la seguente query per creare una nuova tabella.
CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(30) DEFAULT '', `email` varchar(50) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Questa query SQL creerà la struttura dei nostri users
tavolo. Ogni utente avrà un ID autoincrementante, un nome e un indirizzo e-mail.
Possiamo anche riempire il database con gli stessi dati che stiamo attualmente visualizzando tramite un array JSON statico eseguendo un INSERT
interrogazione.
INSERT INTO users (name, email) VALUES ('Richard Hendricks', '[email protected]'), ('Bertram Gilfoyle', '[email protected]');
Non è necessario inserire l'id
campo, poiché si auto-incrementa. A questo punto, abbiamo la struttura della nostra tabella e alcuni dati di esempio con cui lavorare.
Connessione a MySQL
Di nuovo nella nostra app, dobbiamo connetterci a MySQL da Node.js per iniziare a lavorare con i dati. In precedenza, abbiamo installato mysql
npm e ora lo useremo.
Crea una nuova directory chiamata dati e crea un config.js file.
Inizieremo richiedendo il mysql
modulo in data/config.js .
const mysql = require('mysql');
Creiamo un config
oggetto che contiene l'host, l'utente, la password e il database. Questo dovrebbe fare riferimento all'api
database che abbiamo creato e utilizziamo le impostazioni predefinite di localhost.
// Set database connection credentials const config = { host: 'localhost', user: 'root', password: 'root', database: 'api', };
Per motivi di efficienza, creeremo un pool MySQL, che ci consente di utilizzare più connessioni contemporaneamente invece di dover aprire e chiudere manualmente più connessioni.
// Create a MySQL pool const pool = mysql.createPool(config);
Infine, esporteremo il pool MySQL in modo che l'app possa usarlo.
// Export the pool module.exports = pool;
Puoi vedere il file di configurazione del database completato nel nostro repository GitHub.
Ora che ci stiamo connettendo a MySQL e che le nostre impostazioni sono complete, possiamo passare all'interazione con il database dall'API.
Ottenere i dati dell'API da MySQL
Attualmente, il nostro routes.js
sta creando manualmente un array JSON di utenti, simile a questo.
const users = [{ ...
Dal momento che non utilizzeremo più dati statici, possiamo eliminare l'intero array e sostituirlo con un collegamento al nostro pool MySQL.
// Load the MySQL pool connection const pool = require('../data/config');
In precedenza, il GET
per il /users
percorso stava inviando gli users
statici dati. Il nostro codice aggiornato interrogherà invece il database per quei dati. Useremo una query SQL per SELECT
tutto dagli users
tabella, che assomiglia a questa.
SELECT * FROM users
Ecco quali sono i nostri nuovi /users
get route assomiglierà, usando il pool.query()
metodo.
// Display all users app.get('/users', (request, response) => { pool.query('SELECT * FROM users', (error, result) => { if (error) throw error; response.send(result); }); });
Qui stiamo eseguendo SELECT
interrogare e quindi inviare il risultato come JSON al client tramite /users
punto finale. Se riavvii il server e vai a /users
pagina, vedrai gli stessi dati di prima, ma ora è dinamico.
Utilizzo dei parametri URL
Finora, i nostri endpoint sono stati percorsi statici, sia il /
root o /users
—ma che dire di quando vogliamo vedere i dati solo su un utente specifico? Dovremo utilizzare un endpoint variabile.
Per i nostri utenti, potremmo voler recuperare informazioni su ogni singolo utente in base al loro ID univoco. Per farlo, useremmo i due punti (:
) per indicare che si tratta di un parametro di percorso.
// Display a single user by ID app.get('/users/:id', (request, response) => { ... }); });
Possiamo recuperare il parametro per questo percorso con request.params
proprietà. Poiché il nostro si chiama id
, sarà così che lo chiameremo.
const id = request.params.id;
Ora aggiungeremo un WHERE
clausola al nostro SELECT
istruzione per ottenere solo risultati che hanno l'id
specificato .
Useremo ?
come segnaposto per evitare SQL injection e passare l'id come parametro, invece di creare una stringa concatenata, che sarebbe meno sicura.
pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); });
Il codice completo per la nostra risorsa utente individuale ora è simile al seguente:
// Display a single user by ID app.get('/users/:id', (request, response) => { const id = request.params.id; pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); }); });
Ora puoi riavviare il server e accedere a https://localhost/users/2
per vedere solo le informazioni per Gilfoyle. Se ricevi un errore come Cannot GET /users/2
, significa che devi riavviare il server.
L'accesso a questo URL dovrebbe restituire un singolo risultato.
[{ id: 2, name: "Bertram Gilfoyle", email: "[email protected]" }]
Se è quello che vedi, congratulazioni:hai impostato correttamente un parametro di percorso dinamico!
Invio di una richiesta POST
Finora, tutto ciò che abbiamo fatto ha utilizzato GET
richieste. Queste richieste sono sicure, nel senso che non alterano lo stato del server. Abbiamo semplicemente visualizzato i dati JSON.
Ora inizieremo a rendere l'API veramente dinamica usando un POST
richiesta di aggiungere nuovi dati.
Ho menzionato in precedenza nell'articolo Capire REST che non usiamo verbi come add
o delete
nell'URL per l'esecuzione di azioni. Per aggiungere un nuovo utente al database, POST
allo stesso URL da cui li visualizziamo, ma basta impostare un percorso separato per esso.
// Add a new user app.post('/users', (request, response) => { ... });
Nota che stiamo usando app.post()
invece di app.get()
ora.
Dato che stiamo creando invece di leggere, useremo un INSERT
query qui, proprio come abbiamo fatto all'inizializzazione del database. Invieremo l'intero request.body
fino alla query SQL.
pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error;
Inoltre, specificheremo lo stato della risposta come 201
, che sta per Created
. Per ottenere l'ID dell'ultimo elemento inserito, utilizzeremo il insertId
proprietà.
response.status(201).send(`User added with ID: ${result.insertId}`);
Tutto il nostro POST
il codice di ricezione sarà simile a questo.
// Add a new user app.post('/users', (request, response) => { pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error; response.status(201).send(`User added with ID: ${result.insertId}`); }); });
Ora possiamo inviare un POST
richiesta tramite. La maggior parte delle volte quando invii un POST
richiesta, lo stai facendo tramite un modulo web. Impareremo come configurarlo entro la fine di questo articolo, ma il modo più semplice e veloce per inviare un test POST
è con cURL, utilizzando il -d (--data)
bandiera.
Eseguiremo curl -d
, seguito da una stringa di query contenente tutte le coppie chiave/valore e l'endpoint della richiesta.
curl -d "name=Dinesh Chugtai&[email protected]" http://localhost:3002/users
Dopo aver inviato questa richiesta, dovresti ricevere una risposta dal server.
User added with ID: 3
Se accedi a http://localhost/users
, vedrai l'ultima voce aggiunta all'elenco.
Invio di una richiesta PUT
POST
è utile per aggiungere un nuovo utente, ma vorremo usare PUT
per modificare un utente esistente. PUT
è idempotente, il che significa che puoi inviare la stessa richiesta più volte e verrà eseguita una sola azione. Questo è diverso da POST
, perché se inviassimo la nostra nuova richiesta utente più di una volta, continuerebbero a creare nuovi utenti.
Per la nostra API, configureremo PUT
per poter gestire la modifica di un singolo utente, quindi useremo il :id
parametro route questa volta.
Creiamo un UPDATE
query e assicurati che si applichi solo all'ID richiesto con WHERE
clausola. Stiamo usando due ?
segnaposto e i valori che passiamo andranno in ordine sequenziale.
// Update an existing user app.put('/users/:id', (request, response) => { const id = request.params.id; pool.query('UPDATE users SET ? WHERE id = ?', [request.body, id], (error, result) => { if (error) throw error; response.send('User updated successfully.'); }); });
Per il nostro test, modificheremo l'utente 2
e aggiorna l'indirizzo email da [email protected] a [email protected]. Possiamo usare di nuovo cURL, con il [-X (--request)]
flag, per specificare esplicitamente che stiamo inviando una richiesta PUT.
curl -X PUT -d "name=Bertram Gilfoyle" -d "[email protected]" http://localhost:3002/users/2
Assicurati di riavviare il server prima di inviare la richiesta, altrimenti otterrai il Cannot PUT /users/2
errore.
Dovresti vedere questo:
User updated successfully.
I dati utente con ID 2
ora dovrebbe essere aggiornato.
Invio di una richiesta di CANCELLAZIONE
Il nostro ultimo compito per completare la funzionalità CRUD dell'API è creare un'opzione per eliminare un utente dal database. Questa richiesta utilizzerà il DELETE
Query SQL con WHERE
e cancellerà un singolo utente specificato da un parametro di percorso.
// Delete a user app.delete('/users/:id', (request, response) => { const id = request.params.id; pool.query('DELETE FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send('User deleted.'); }); });
Possiamo usare -X
di nuovo con cURL per inviare l'eliminazione. Eliminiamo l'ultimo utente che abbiamo creato.
curl -X DELETE http://localhost:3002/users/3
Vedrai il messaggio di successo.
User deleted.
Vai a http://localhost:3002
e vedrai che ora ci sono solo due utenti.
Congratulazioni! A questo punto, l'API è completa. Visita il repository GitHub per vedere il codice completo per routes.js .
Invio di richieste tramite la request
Modulo
All'inizio di questo articolo, abbiamo installato quattro dipendenze e una di queste era la request
modulo. Invece di utilizzare le richieste cURL, puoi creare un nuovo file con tutti i dati e inviarlo. Creerò un file chiamato post.js che creerà un nuovo utente tramite POST
.
const request = require('request'); const json = { "name": "Dinesh Chugtai", "email": "[email protected]", }; request.post({ url: 'http://localhost:3002/users', body: json, json: true, }, function (error, response, body) { console.log(body); });
Possiamo chiamarlo usando node post.js
in una nuova finestra del terminale mentre il server è in esecuzione e avrà lo stesso effetto dell'utilizzo di cURL. Se qualcosa non funziona con cURL, la request
modulo è utile in quanto possiamo visualizzare l'errore, la risposta e il corpo.
Invio di richieste tramite modulo Web
Di solito, POST
e altri metodi HTTP che alterano lo stato del server vengono inviati utilizzando moduli HTML. In questo esempio molto semplice, possiamo creare un index.html file ovunque e crea un campo per un nome e un indirizzo e-mail. L'azione del modulo punterà alla risorsa, in questo caso http//localhost:3002/users
e specificheremo il metodo come post
.
Crea index.html e aggiungi il seguente codice:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Node.js Express REST API</title> </head> <body> <form action="http://localhost:3002/users" method="post"> <label for="name">Name</label> <input type="text" name="name"> <label for="email">Email</label> <input type="email" name="email"> <input type="submit"> </form> </body> </html>
Apri questo file HTML statico nel tuo browser, compilalo e invialo mentre il server è in esecuzione nel terminale. Dovresti vedere la risposta di User added with ID: 4
e dovresti essere in grado di visualizzare il nuovo elenco di utenti.