sql >> Databasteknik >  >> RDS >> Mysql

Koda ditt första API med Node.js och Express:Anslut en databas

Bygg ett REST API med Node.js och Express:Ansluta en databas

I den första handledningen, Understanding RESTful APIs, lärde vi oss vad REST-arkitekturen är, vad HTTP-begäransmetoder och -svar är och hur man förstår en RESTful API-slutpunkt. I den andra handledningen, Hur man ställer in en Express API-server, lärde vi oss hur man bygger servrar med båda Nodes inbyggda http modulen och Express-ramverket, och hur man dirigerar appen vi skapade till olika URL-slutpunkter.

För närvarande använder vi statisk data för att visa användarinformation i form av ett JSON-flöde när API-slutpunkten träffas med en GET begäran. I den här handledningen kommer vi att ställa in en MySQL-databas för att lagra all data, ansluta till databasen från vår Node.js-app och tillåta API:et att använda GET , POST , PUT och DELETE metoder för att skapa ett komplett API.

Installation

Hittills har vi inte använt en databas för att lagra eller manipulera någon data, så vi kommer att sätta upp en. Den här handledningen kommer att använda MySQL, och om du redan har MySQL installerat på din dator är du redo att gå vidare till nästa steg.

Om du inte har MySQL installerat kan du ladda ner MAMP för macOS och Windows, som ger en gratis lokal servermiljö och databas. När du har laddat ner detta öppnar du programmet och klickar på Starta servrar för att starta MySQL.

Förutom att ställa in själva MySQL, vill vi att GUI-programvaran ska se databasen och tabellerna. För Mac, ladda ner SequelPro och för Windows ladda ner SQLyog. När du har laddat ner och kört MySQL kan du använda SequelPro eller SQLyog för att ansluta till localhost med användarnamnet root och lösenord root på port 3306 .

När allt är inställt här kan vi gå vidare till att ställa in databasen för vårt API.

Konfigurera databasen

Lägg till en ny databas i din databasvisningsprogramvara och kalla den api . Se till att MySQL körs, annars kommer du inte att kunna ansluta till localhost .

När du har api databas skapad, flytta in i den och kör följande fråga för att skapa en ny tabell.

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;

Denna SQL-fråga kommer att skapa strukturen för våra users tabell. Varje användare kommer att ha ett auto-inkrementerande ID, ett namn och en e-postadress.

Vi kan också fylla databasen med samma data som vi för närvarande visar genom en statisk JSON-array genom att köra en INSERT fråga.

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

Du behöver inte ange id fältet, eftersom det ökar automatiskt. Vid det här laget har vi strukturen för vår tabell samt några exempeldata att arbeta med.

Ansluter till MySQL

Tillbaka i vår app måste vi ansluta till MySQL från Node.js för att börja arbeta med datan. Tidigare installerade vi mysql npm-modul, och nu ska vi använda den.

Skapa en ny katalog som heter data och gör en config.js fil.

Vi börjar med att kräva mysql modul i data/config.js .

const mysql = require('mysql');

Låt oss skapa en config objekt som innehåller värden, användaren, lösenordet och databasen. Detta bör referera till api databas vi skapade och använder standardinställningarna för localhost.

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

För effektivitetens skull kommer vi att skapa en MySQL-pool, som gör att vi kan använda flera anslutningar samtidigt istället för att manuellt behöva öppna och stänga flera anslutningar.

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

Slutligen kommer vi att exportera MySQL-poolen så att appen kan använda den.

// Export the pool
module.exports = pool;

Du kan se den färdiga databaskonfigurationsfilen i vår GitHub-repo.

Nu när vi ansluter till MySQL och våra inställningar är klara, kan vi gå vidare till att interagera med databasen från API:t.

Hämta API-data från MySQL

För närvarande är vår routes.js filen skapar manuellt en JSON-array av användare, som ser ut så här.

const users = [{ ...

Eftersom vi inte längre kommer att använda statisk data, kan vi ta bort hela arrayen och ersätta den med en länk till vår MySQL-pool.

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

Tidigare var GET för /users sökvägen skickade de statiska users data. Vår uppdaterade kod kommer att fråga databasen efter den datan istället. Vi kommer att använda en SQL-fråga för att SELECT allt från users tabell, som ser ut så här.

SELECT * FROM users

Här är vad våra nya /users get route kommer att se ut med pool.query() metod.

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

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

Här kör vi SELECT fråga och sedan skicka resultatet som JSON till klienten via /users slutpunkt. Om du startar om servern och navigerar till /users sida, kommer du att se samma data som tidigare, men nu är den dynamisk.

Använda URL-parametrar

Hittills har våra slutpunkter varit statiska vägar – antingen / root eller /users — men hur är det när vi bara vill se data om en specifik användare? Vi måste använda en variabel slutpunkt.

För våra användare kanske vi vill hämta information om varje enskild användare baserat på deras unika id. För att göra det skulle vi använda ett kolon (: ) för att ange att det är en ruttparameter.

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

Vi kan hämta parametern för denna sökväg med request.params fast egendom. Eftersom vårt heter id , det är så vi refererar till det.

const id = request.params.id;

Nu lägger vi till en WHERE klausul till vår SELECT för att bara få resultat som har det angivna id .

Vi använder ? som en platshållare för att undvika SQL-injektion och skicka igenom ID:t som en parameter, istället för att bygga en sammanlänkade sträng, vilket skulle vara mindre säkert.

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

    response.send(result);
});

Den fullständiga koden för vår individuella användarresurs ser nu ut så här:

// 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 starta om servern och navigera till https://localhost/users/2 för att bara se informationen för Gilfoyle. Om du får ett felmeddelande som Cannot GET /users/2 , betyder det att du måste starta om servern.

Att gå till den här webbadressen bör returnera ett enda resultat.

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

Om det är vad du ser, grattis:du har framgångsrikt konfigurerat en dynamisk ruttparameter!

Skicka en POST-förfrågan

Hittills har allt vi har gjort använt GET förfrågningar. Dessa förfrågningar är säkra, vilket innebär att de inte ändrar serverns tillstånd. Vi har helt enkelt tittat på JSON-data.

Nu ska vi börja göra API:t verkligt dynamiskt genom att använda en POST begära att lägga till nya data.

Jag nämnde tidigare i Understanding REST-artikeln att vi inte använder verb som add eller delete i URL:en för att utföra åtgärder. För att lägga till en ny användare till databasen, POST till samma URL som vi ser dem från, men ställ bara in en separat rutt för det.

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

Observera att vi använder app.post() istället för app.get() nu.

Eftersom vi skapar istället för att läsa, använder vi en INSERT fråga här, ungefär som vi gjorde vid initieringen av databasen. Vi skickar hela request.body till SQL-frågan.

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

Vi kommer också att ange status för svaret som 201 , som står för Created . För att få ID för det senast infogade objektet använder vi insertId egendom.

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

Hela vår POST mottagningskoden kommer att se ut så här.

// 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 skicka en POST begära igenom. För det mesta när du skickar en POST begäran gör du det via ett webbformulär. Vi lär oss hur du ställer in det i slutet av den här artikeln, men det snabbaste och enklaste sättet att skicka ett test POST är med cURL, med -d (--data) flagga.

Vi kör curl -d , följt av en frågesträng som innehåller alla nyckel/värdepar och begärans slutpunkt.

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

När du har skickat igenom denna begäran bör du få ett svar från servern.

User added with ID: 3

Om du navigerar till http://localhost/users , kommer du att se den senaste posten som lagts till i listan.

Skicka en PUT-förfrågan

POST är användbart för att lägga till en ny användare, men vi vill använda PUT för att ändra en befintlig användare. PUT är idempotent, vilket innebär att du kan skicka samma begäran flera gånger och endast en åtgärd kommer att utföras. Detta är annorlunda än POST , för om vi skickade igenom vår nya användarförfrågan mer än en gång, skulle den fortsätta att skapa nya användare.

För vårt API kommer vi att ställa in PUT för att kunna hantera redigering av en enskild användare, så vi kommer att använda :id ruttparameter den här gången.

Låt oss skapa en UPDATE fråga och se till att den endast gäller det begärda ID:t med WHERE klausul. Vi använder två ? platshållare, och de värden vi skickar kommer att gå i sekventiell ordning.

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

För vårt test kommer vi att redigera användare 2 och uppdatera e-postadressen från [email protected] till [email protected]. Vi kan använda cURL igen, med [-X (--request)] flagga, för att uttryckligen ange att vi skickar en PUT-förfrågan.

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

Se till att starta om servern innan du skickar begäran, annars får du Cannot PUT /users/2 fel.

Du bör se detta:

User updated successfully.

Användardata med id 2 bör nu uppdateras.

Skicka en DELETE-förfrågan

Vår sista uppgift för att slutföra CRUD-funktionaliteten i API:t är att skapa ett alternativ för att ta bort en användare från databasen. Denna begäran kommer att använda DELETE SQL-fråga med WHERE , och det kommer att ta bort en enskild användare specificerad av en ruttparameter.

// 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 använda -X igen med cURL för att skicka bort raderingen. Låt oss ta bort den senaste användaren vi skapade.

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

Du kommer att se framgångsmeddelandet.

User deleted.

Navigera till http://localhost:3002 , och du kommer att se att det bara finns två användare nu.

Grattis! Vid denna tidpunkt är API:et komplett. Besök GitHub-repo för att se den fullständiga koden för routes.js .

Skicka förfrågningar genom request Modul

I början av den här artikeln installerade vi fyra beroenden, och ett av dem var request modul. Istället för att använda cURL-förfrågningar kan du skapa en ny fil med all data och skicka igenom den. Jag skapar en fil som heter post.js som skapar en ny användare 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 kalla detta med node post.js i ett nytt terminalfönster medan servern körs, och det kommer att ha samma effekt som att använda cURL. Om något inte fungerar med cURL, request modulen är användbar eftersom vi kan se felet, svaret och texten.

Skicka förfrågningar via ett webbformulär

Vanligtvis POST och andra HTTP-metoder som ändrar serverns tillstånd skickas med HTML-formulär. I detta mycket enkla exempel kan vi skapa en index.html fil var som helst och skapa ett fält för ett namn och en e-postadress. Formulärets åtgärd kommer att peka på resursen, i det här fallet http//localhost:3002/users , och vi kommer att specificera metoden som post .

Skapa index.html och lägg till följande kod till den:

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

Öppna denna statiska HTML-fil i din webbläsare, fyll i den och skicka den medan servern körs i terminalen. Du bör se svaret från User added with ID: 4 , och du bör kunna se den nya listan med användare.


  1. Returnera en lista över database-postprofiler i SQL Server (T-SQL)

  2. FEL 1045 (28000):Åtkomst nekad för användaren 'root'@'localhost' (med lösenord:JA)

  3. Problemet med förlorad uppdatering i samtidiga transaktioner

  4. MySQL främmande nyckel begränsningar, kaskad radering