Node.js backend

Siin tutorialis loome enda Node.js Express backendi, kus kasutame lokaalselt hostitud PostgreSQL andmebaasi. Eeldame, et olete läbinud React.js frontend tutoriali, või omate oskuseid sarnase tehnoloogiaga (nt Vue.js, Angular vms).

PostgreSQL allalaadimine

PostgreSQL allalaadimiseks külastage PostgreSQL ametlikku lehte.

Esimesel lehel valige Windows ja seejärel Download the installer. Avanenud tabelis valige PostgreSQL 17 versioon ja Windows x86-64. Seejärel avage alla laaditud fail.

Klõpsake Next, jättes kõik vaikesätted kuni Password leheni, kus saate superkasutaja kontole valida parooli vastavalt oma eelistusele.

../_images/image-pg-1.png

Seejärel klõpsake taas Next ja jätkake vaikeseadetega. Oodake, kuni installatsioon lõpeb ja ilmub Completing the PostgreSQL Setup Wizard aken. Seal eemaldage valik Stack Builder, kuna me ei vaja täiendavate teenuste installimist.

../_images/image-pg-2.png

Nüüd peaks PostgreSQL olema installitud. Kui vajate täiendavat juhendit, võite ka netist abi otsida.

Andmebaasi loomine

Kui PostgreSQL on installitud, loome command line'i või pgAdmin interface'i kasutades projekti jaoks andmebaasi. Teeme selle siin läbi command line'iga.

Ühendame PostgreSQL interactive shelliga:

psql -U postgres

Või, kui teil on parool:

psql -U postgres -h localhost -W

Loome andmebaasi:

CREATE DATABASE veebiprojekt_demo;

(Võite andmebaasile enda soovitud nime panna.)

Ja lahkume psql shell'ist käsuga:

\q

Projektistruktuur

Enda projekti repos, kui frontend kaust on kinni, peaks seal olema ainult frontend kaust ja README.md fail. Sinna samale kausta tasemele looge uus kaust nimega backend.

Avage terminal ja minge enda backend kausta sisse:

cd backend

Looge Node.js projekt käsuga:

npm init -y

Installige projektiks vajalikud npm package'id:

npm install express pg cors dotenv

(Express on web application framework, pg on PostgreSQL client, cors on middleware et CORS lubada ja dotenv et .env faile lugeda.)

.env faili loomine

Loome backend kausta faili, nimega .env, tähtis on ka punkt!

Sinna sisse paneme sisu:

DATABASE_URL=postgres://postgres:parool@localhost:5432/andmebaasi_nimi
PORT=5000

Kus parool ja andmebaasi nimi asendage enda valikutega.

Mis on .env fail?

.gitignore faili loomine

Loome ka .gitignore faili, mille sisu on järgnev:

# Node modules
node_modules/

# Environment variables
.env

Mis on .gitignore fail?

index.js faili loomine

Loome backend kausta uue faili nimega index.js, mille sisu on järgnev:

Serveri tööle panemine

Nüüd paneme serveri tööle, kuid et backend koodi muutes server automaatselt uuenduks, installime nodemon package'i. Selle jaoks teeme terminalis, backend kaustas:

npm install --save-dev nodemon

Ja muudame enda package.json sisu järgnevaks:

{
  "type": "module",
  "name": "backend",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^16.4.5",
    "express": "^4.21.0",
    "pg": "^8.13.0"
  },
  "devDependencies": {
    "nodemon": "^3.1.7"
  }
}

Nüüd alustame enda backend serverit käsuga:

npm run dev

Avades http://localhost:5000 peaksime nägema enda “/” endpoint'i sisu, ehk “Hello, World!”.

  • Kui server ei avane, kontrollige, kas jooksutasite antud käsklust ikka /backend pathi seest.

Proovige muuta "/" endpoint'i sisu ja lehte refreshides peaks sisu automaatselt muutuma.

app.get("/", (req, res) => {
    res.send("Hello, World!");
});

Andmebaasi tabeli loomine

Loome PostgreSQL andmebaasis users nimelise tabeli, kus on name ja age veerud. Sinna saame pärast lisada inimesi ja neid enda projekti frontendis kuvada.

  1. Ühendage PostgreSQL interactive shelliga:

    psql -U postgres -h localhost -W
    
  2. Valige loodud andmebaas:

    \c veebiprojekt_demo;
    
  3. Looge users tabel:

    CREATE TABLE users (
        id SERIAL PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        age INT NOT NULL
    );
    

Endpointide loomine

Mis on GET, POST, PUT ja DELETE?

Mis on endpoint?

Lisame GET ja POST endpoint'id index.js faili:

// GET endpoint, et kuvada kõiki kasutajaid andmebaasist
app.get("/users", async (req, res) => {
    try {
        // SQL päring andmebaasist 'users' tabelist
        const result = await pool.query("SELECT * FROM users");
        // Tagastame saadud päringu tulemuse JSON formaadis
        res.json(result.rows);
    } catch (err) {
        // Kui tekib viga, kuvame seda konsoolis ja saadame kliendile veateate
        console.error(err);
        res.status(500).send("Server error");
    }
});

// POST endpoint, et lisada uus kasutaja
app.post("/users", async (req, res) => {
    // Võtame päringu body'st välja name ja age väärtused
    // (siin eeldame, et backendiga ühendatud frontend saadab meile /users endpointi korral nime ja vanuse)
    const { name, age } = req.body;
    try {
        // SQL päring, mis lisab 'users' tabelisse uue kasutaja
        const result = await pool.query(
            "INSERT INTO users (name, age) VALUES ($1, $2) RETURNING *",
            [name, age]
        );
        // Tagastame kliendile päringu tulemuse
        res.status(201).json(result.rows[0]);
    } catch (err) {
        // Kui tekib viga, kuvame seda konsoolis ja saadame kliendile veateate
        console.error(err);
        res.status(500).send("Server error");
    }
});

Frontendiga ühendamine

Nüüd muudame enda frontendi faili Meist.jsx, et kasutada andmeid backend andmebaasist ja võimaldada uute kasutajate lisamist.

import { useEffect, useState } from "react";
import ContactCard from "../components/ContactCard";

function Meist() {
    const [contacts, setContacts] = useState([]);
    const [name, setName] = useState("");
    const [age, setAge] = useState("");

    // Andmete laadimine serverist, käivitub vaid korra
    useEffect(() => {
        // Asünkroonne funktsioon, et pärida kasutajad serverist
        const fetchContacts = async () => {
            const response = await fetch("http://localhost:5000/users"); // Pärime serverilt kasutajate andmed
            const data = await response.json(); // Teisendame vastuse JSON-iks
            setContacts(data); // Salvestame saadud andmed
        };

        fetchContacts(); // Kutsume välja üleval loodud funktsiooni
    }, []);

    // Uue kasutaja lisamine
    const addContact = async (e) => {
        e.preventDefault(); // Väldime lehe refreshi
        // Saadame enne loodud backend POST endpointi päringu
        const response = await fetch("http://localhost:5000/users", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({ name, age }), // Saadame kasutaja nime ja vanuse serverile
        });

        // Kui päring õnnestub, uuendame kontaktide loendit
        if (response.ok) {
            // Uuendame kontaktide loendit, lisades uue kasutaja olemasolevatele
            const newContact = await response.json();
            setContacts((prevContacts) => [...prevContacts, newContact]);
            // Tühjendame vormi väljad
            setName("");
            setAge("");
        }
    };

    return (
        <div>
            <h2>Meist</h2>
            <p>Tekst teie endi kohta!</p>

            <form onSubmit={addContact}>
                <input
                    type="text"
                    placeholder="Nimi"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    required
                />
                <input
                    type="number"
                    placeholder="Vanus"
                    value={age}
                    onChange={(e) => setAge(e.target.value)}
                    required
                />
                <button type="submit">Lisa kasutaja</button>
            </form>

            {contacts.map((contact) => (
                <ContactCard key={contact.id} name={contact.name} age={contact.age} />
            ))}
        </div>
    );
}

export default Meist;

Edasiseks

Nüüd peaks valmis olema töötav fullstack veebirakendus React.js frontendi ja Node.js/Express.js + PostgreSQL põhjal. Edasi saaks antud projektile hakata lisama veel frontend lehti, componente ja samuti uusi backend endpointe, mis lisavad lehele veel funktsionaalsust. Soovitan proovida teil olemasolevate endpointide järgi uusi endpointe luua, et läbi praktika selles tugevamaks saada. Samuti on internet täis materjale, youtube, google, misiganes teile rohkem meeldib.