sql >> Database teknologi >  >> RDS >> Mysql

Kod din første API med Node.js og Express:Tilslut en database

Byg en REST API med Node.js og Express:Tilslutning af en database

I den første tutorial, Understanding RESTful API'er, lærte vi, hvad REST-arkitekturen er, hvad HTTP-anmodningsmetoder og -svar er, og hvordan man forstår et RESTful API-slutpunkt. I den anden vejledning, Sådan opsætter du en Express API-server, lærte vi, hvordan man bygger servere med begge Nodes indbyggede http modul og Express-rammen, og hvordan man dirigerer den app, vi oprettede, til forskellige URL-endepunkter.

I øjeblikket bruger vi statiske data til at vise brugeroplysninger i form af et JSON-feed, når API-endepunktet rammes med en GET anmodning. I denne vejledning skal vi opsætte en MySQL-database til at gemme alle data, oprette forbindelse til databasen fra vores Node.js-app og tillade API'en at bruge GET , POST , PUT og DELETE metoder til at skabe en komplet API.

Installation

Indtil nu har vi ikke brugt en database til at gemme eller manipulere nogen data, så vi vil oprette en. Denne vejledning vil bruge MySQL, og hvis du allerede har MySQL installeret på din computer, er du klar til at gå videre til næste trin.

Hvis du ikke har MySQL installeret, kan du downloade MAMP til macOS og Windows, som giver et gratis, lokalt servermiljø og database. Når du har downloadet dette, skal du åbne programmet og klikke på Start servere for at starte MySQL.

Ud over at konfigurere selve MySQL, vil vi have GUI-software til at se databasen og tabellerne. Til Mac skal du downloade SequelPro, og til Windows skal du downloade SQLyog. Når du har MySQL downloadet og kørt, kan du bruge SequelPro eller SQLyog til at oprette forbindelse til localhost med brugernavnet root og adgangskode root på port 3306 .

Når alt er sat op her, kan vi gå videre til opsætning af databasen til vores API.

Opsætning af databasen

Tilføj en ny database i din databasevisningssoftware og kald den api . Sørg for, at MySQL kører, ellers vil du ikke være i stand til at oprette forbindelse til localhost .

Når du har api database oprettet, flyt ind i den og kør følgende forespørgsel for at oprette en ny tabel.

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;

Denne SQL-forespørgsel vil skabe strukturen for vores users bord. Hver bruger vil have et auto-inkrementerende id, et navn og en e-mailadresse.

Vi kan også fylde databasen med de samme data, som vi i øjeblikket viser gennem et statisk JSON-array ved at køre en INSERT forespørgsel.

INSERT INTO users (name, email) 
     VALUES ('Richard Hendricks', '[email protected]'), 
            ('Bertram Gilfoyle',  '[email protected]');

Det er ikke nødvendigt at indtaste id felt, da det er automatisk inkrementerende. På dette tidspunkt har vi strukturen i vores tabel samt nogle eksempeldata at arbejde med.

Opretter forbindelse til MySQL

Tilbage i vores app skal vi oprette forbindelse til MySQL fra Node.js for at begynde at arbejde med dataene. Tidligere installerede vi mysql npm-modul, og nu skal vi bruge det.

Opret en ny mappe kaldet data og lav en config.js fil.

Vi starter med at kræve mysql modul i data/config.js .

const mysql = require('mysql');

Lad os oprette en config objekt, der indeholder værten, brugeren, adgangskoden og databasen. Dette bør referere til api database, vi har lavet og bruger standardindstillingerne for localhost.

// Set database connection credentials
const config = {
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'api',
};

For effektivitetens skyld vil vi oprette en MySQL-pool, som giver os mulighed for at bruge flere forbindelser på én gang i stedet for manuelt at skulle åbne og lukke flere forbindelser.

// Create a MySQL pool
const pool = mysql.createPool(config);

Til sidst eksporterer vi MySQL-puljen, så appen kan bruge den.

// Export the pool
module.exports = pool;

Du kan se den færdige databasekonfigurationsfil i vores GitHub-repo.

Nu hvor vi opretter forbindelse til MySQL, og vores indstillinger er færdige, kan vi gå videre til at interagere med databasen fra API'et.

Hent API-data fra MySQL

I øjeblikket er vores routes.js fil opretter manuelt en JSON-array af brugere, som ser sådan ud.

const users = [{ ...

Da vi ikke længere kommer til at bruge statiske data, kan vi slette hele det array og erstatte det med et link til vores MySQL-pool.

// Load the MySQL pool connection
const pool = require('../data/config');

Tidligere var GET for /users stien sendte de statiske users data. Vores opdaterede kode vil i stedet forespørge databasen om disse data. Vi skal bruge en SQL-forespørgsel til at SELECT alt fra users tabel, som ser sådan ud.

SELECT * FROM users

Her er hvad vores nye /users get-ruten vil se ud ved at bruge pool.query() metode.

// Display all users
app.get('/users', (request, response) => {
    pool.query('SELECT * FROM users', (error, result) => {
        if (error) throw error;

        response.send(result);
    });
});

Her kører vi SELECT forespørgsel og derefter sende resultatet som JSON til klienten via /users endepunkt. Hvis du genstarter serveren og navigerer til /users side, vil du se de samme data som før, men nu er det dynamisk.

Brug af URL-parametre

Indtil videre har vores endepunkter været statiske stier – enten / root eller /users — men hvad med, når vi kun vil se data om en bestemt bruger? Vi bliver nødt til at bruge et variabelt slutpunkt.

For vores brugere ønsker vi måske at hente oplysninger om hver enkelt bruger baseret på deres unikke id. For at gøre det, ville vi bruge et kolon (: ) for at angive, at det er en ruteparameter.

// Display a single user by ID
app.get('/users/:id', (request, response) => {
        ...
    });
});

Vi kan hente parameteren for denne sti med request.params ejendom. Da vores hedder id , det vil være sådan, vi omtaler det.

const id = request.params.id;

Nu tilføjer vi en WHERE klausul til vores SELECT sætning for kun at få resultater, der har det angivne id .

Vi bruger ? som en pladsholder for at undgå SQL-injektion og sende id'et igennem som en parameter i stedet for at bygge en sammenkædet streng, hvilket ville være mindre sikkert.

pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => {
    if (error) throw error;

    response.send(result);
});

Den fulde kode for vores individuelle brugerressource ser nu sådan ud:

// 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);
    });
});

Nu kan du genstarte serveren og navigere til https://localhost/users/2 for kun at se oplysningerne om Gilfoyle. Hvis du får en fejl som Cannot GET /users/2 , betyder det, at du skal genstarte serveren.

Hvis du går til denne URL, skulle det returnere et enkelt resultat.

[{
    id: 2,
    name: "Bertram Gilfoyle",
    email: "[email protected]"
}]

Hvis det er det, du ser, tillykke:du har opsat en dynamisk ruteparameter!

Send en POST-anmodning

Indtil videre har alt, hvad vi har lavet, brugt GET anmodninger. Disse anmodninger er sikre, hvilket betyder, at de ikke ændrer serverens tilstand. Vi har simpelthen set JSON-data.

Nu skal vi begynde at gøre API'en virkelig dynamisk ved at bruge en POST anmode om at tilføje nye data.

Jeg nævnte tidligere i artiklen Understanding REST, at vi ikke bruger verber som add eller delete i URL'en for at udføre handlinger. For at tilføje en ny bruger til databasen, POST til den samme URL, som vi ser dem fra, men opsæt bare en separat rute for det.

// Add a new user
app.post('/users', (request, response) => {
    ...
});

Bemærk, at vi bruger app.post() i stedet for app.get() nu.

Da vi opretter i stedet for at læse, bruger vi en INSERT forespørgsel her, ligesom vi gjorde ved initialiseringen af ​​databasen. Vi sender hele request.body videre til SQL-forespørgslen.

pool.query('INSERT INTO users SET ?', request.body, (error, result) => {
    if (error) throw error;

Vi vil også angive status for svaret som 201 , som står for Created . For at få id'et for det sidst indsatte element, bruger vi insertId ejendom.

response.status(201).send(`User added with ID: ${result.insertId}`);

Hele vores POST modtage kode vil se sådan ud.

// 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}`);
    });
});

Nu kan vi sende en POST anmodning igennem. Det meste af tiden, når du sender en POST anmodning, gør du det via en webformular. Vi lærer, hvordan du sætter det op i slutningen af ​​denne artikel, men den hurtigste og nemmeste måde at sende en test POST på er med cURL ved hjælp af -d (--data) flag.

Vi kører curl -d , efterfulgt af en forespørgselsstreng, der indeholder alle nøgle/værdi-parrene og anmodningens slutpunkt.

curl -d "name=Dinesh Chugtai&[email protected]" http://localhost:3002/users

Når du har sendt denne anmodning igennem, bør du få et svar fra serveren.

User added with ID: 3

Hvis du navigerer til http://localhost/users , vil du se den seneste post tilføjet til listen.

Send en PUT-anmodning

POST er nyttig til at tilføje en ny bruger, men vi vil gerne bruge PUT at ændre en eksisterende bruger. PUT er idempotent, hvilket betyder, at du kan sende den samme anmodning igennem flere gange, og kun én handling vil blive udført. Dette er anderledes end POST , for hvis vi sendte vores nye brugeranmodning igennem mere end én gang, ville den blive ved med at oprette nye brugere.

For vores API skal vi konfigurere PUT for at kunne håndtere redigering af en enkelt bruger, så vi kommer til at bruge :id ruteparameter denne gang.

Lad os oprette en UPDATE forespørgsel og sørg for, at den kun gælder for det anmodede id med WHERE klausul. Vi bruger to ? pladsholdere, og de værdier, vi videregiver, vil gå i sekventiel rækkefølge.

// 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.');
    });
});

Til vores test vil vi redigere bruger 2 og opdater e-mailadressen fra [email protected] til [email protected]. Vi kan bruge cURL igen med [-X (--request)] flag, for eksplicit at angive, at vi sender en PUT-anmodning igennem.

curl -X PUT -d "name=Bertram Gilfoyle" -d "[email protected]" http://localhost:3002/users/2

Sørg for at genstarte serveren, før du sender anmodningen, ellers får du koden Cannot PUT /users/2 fejl.

Du bør se dette:

User updated successfully.

Brugerdataene med id 2 skal nu være opdateret.

Send en SLETTE-anmodning

Vores sidste opgave for at fuldføre API'ets CRUD-funktionalitet er at lave en mulighed for at slette en bruger fra databasen. Denne anmodning vil bruge DELETE SQL-forespørgsel med WHERE , og det vil slette en individuel bruger angivet af en ruteparameter.

// 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.');
    });
});

Vi kan bruge -X igen med cURL for at sende sletningen igennem. Lad os slette den seneste bruger, vi har oprettet.

curl -X DELETE http://localhost:3002/users/3

Du vil se succesmeddelelsen.

User deleted.

Naviger til http://localhost:3002 , og du vil se, at der kun er to brugere nu.

Tillykke! På dette tidspunkt er API'en færdig. Besøg GitHub-reposen for at se den komplette kode for routes.js .

Send anmodninger gennem request Modul

I begyndelsen af ​​denne artikel installerede vi fire afhængigheder, og en af ​​dem var request modul. I stedet for at bruge cURL-anmodninger kan du lave en ny fil med alle data og sende den igennem. Jeg opretter en fil kaldet post.js der vil oprette en ny bruger via 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);
});

Vi kan kalde dette ved at bruge node post.js i et nyt terminalvindue, mens serveren kører, og det vil have samme effekt som at bruge cURL. Hvis noget ikke virker med cURL, skal du request modul er nyttigt, da vi kan se fejlen, svaret og brødteksten.

Afsendelse af anmodninger via en webformular

Normalt POST og andre HTTP-metoder, der ændrer serverens tilstand, sendes ved hjælp af HTML-formularer. I dette meget enkle eksempel kan vi oprette en index.html fil hvor som helst, og lav et felt til et navn og en e-mailadresse. Formularens handling vil pege på ressourcen, i dette tilfælde http//localhost:3002/users , og vi angiver metoden som post .

Opret index.html og tilføj følgende kode til det:

<!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>

Åbn denne statiske HTML-fil i din browser, udfyld den, og send den, mens serveren kører i terminalen. Du bør se svaret fra User added with ID: 4 , og du bør være i stand til at se den nye liste over brugere.


  1. SQL-forespørgsel til at opdele kolonnedata i rækker

  2. mySQL-fejl 1040:For mange forbindelser

  3. Oracle TNS-navne vises ikke, når der tilføjes ny forbindelse til SQL Developer

  4. Er der en måde at vise en WHERE-klausul kun for et felt i MySQL?