Databasen

Webbserverprogrammering 1

Vad är en databas?

  • En  organiserad samling av data (data = information) på ett sådant sätt att det är lätt att söka efter och hämta enskilda bitar information, samt även ändra informationen.
  • Är persistent, d.v.s försvinner inte när man avslutar programmet eller stänger av datorn.
  • Om man vill skapa en databas vill man gör en modell som beskriver verkligheten. Till exempel göra en beskrivning hur en webbutik ser ut och fungerar (produkter, priser, kunder, lagerstatus...). Eller i vårt fall en blog (användare, inlägg, kommenterar, bilder..).

Olika databaser

  • Det finns flera olika databaser. En vanlig uppdelning är mellan relationsdatabaser (SQL) och icke-relationsdatabaser (NoSQL).
  • En relationsdatabas som SQL eller mySQL är uppbyggt av tabeller
  • En icke-relationsdatabas som MongoDB är uppbyggt av dokument. 
  • I stacken Node.js + Express är MongoDB vanligast och den databas vi ska använda mest i kursen.
  • Vi kommer även studera en mySQL-databas översiktligt senare i kursen.

Introduktion till MongoDB

Text

Databas

COLLECTION

innehåller ett flertal  "document" 

NoSQL

DOCUMENT

innehåller "key-value pairs"

 

DATABAS innehåller en eller flera "collections" såsom users, posts, etc.

SQL

"Tabell"

"Rader"

Komma igång med MongoDB

Text

Olika alternativ:

  • Installera en lokal databas med Mongo Shell
  • Skapa en "hostad" databas på molntjänsten MongoDB Atlas - vi väljer detta i kursen då det är lättast att komma igång med

Skapa databas i molnet med MongoDB Atlas

Text

  1. Gå till https://www.mongodb.com/cloud/atlas
  2. Skapa konto och logga in
  3. Välj "Build New Cluster"
  4. Välj en av "Free tier available" och tryck "Create Cluster"
  5. Kan ta några minuter...
  6. Gå till "Network Access" och välj "Add IP-adress" för att sätta din IP-adress på "whitelist".
  7. Gå till "Database Access" för att skapa en användare till ditt cluster. Spara lösenordet.
  8. Gå till ditt cluster och välj "Connect" och välj sedan "Connect Your Application"
  9. Kopiera och spara din "connection string". Där det står <password> kommer du behöva ersätta med det sparade lösenordet i 7)
  10. I nästa del visas hur du använder din "connection string" i din applikation för att upprätta kontakt med din databas. 

Innan vi sätter upp databaskonfigurationen...

Behöver vi hantera e variabler som är beroende på vilken utvecklingsmiljö programmet körs på, eller inställningar på servern. 

Dessa variabler som exempelvis port, databasuppkoppling, databasnamn, användarnam, lösenord, m. fl., kallas för miljövariabler (eng. environment variables) och behöver hanteras separat och vara åtskilda från applikationen (exempelvis i egen fil)

D.v.s en vacker dag vill vi drifta vår applikation från att köra lokalt till live på internet :-)

Hur kan vi använda miljövariabler i Node.js?

Smidigt med npm-modulen dotenv där man enkelt kan läsa in miljövariablerna från en egen fil.

npm install dotenv

Hur kan vi använda miljövariabler i Node.js?

const dotenv = require("dotenv");

// Ange sökvägen till vår .env-fil
dotenv.config({path: "./config.env"});

/* Hämta en miljövariabel 
   med process.env.VARIABELNAMN */
const port = process.env.PORT;

const DB = process.env.DATABASE.replace(
  "<PASSWORD>",
  process.env.DATABASE_PASSWORD
);

Skapa filen config.env i roten

NODE_ENV=development
PORT=3000
DATABASE=XXX
DATABASE_PASSWORD=XXX

app.js

Din "connection string" från MongoDB Atlas

Filen config.env i roten

NODE_ENV=development
PORT=3000
DATABASE=mongodb+srv://sanla:<PASSWORD>@cluster0-pzfk4.mongodb.net/blog?retryWrites=true&w=majority
DATABASE_PASSWORD=XXX

+ lösenordet när du skapade en användare till ditt cluster

Här kan du byta namnet på databasen från test till exempelvis blog

Mongoose

Mongoose är ett bibliotek som sköter databashantering för MongoDB på Node.js

Det är Mongoose funktioner vi kommer använda för databasuppkoppling, skapa modell för våra inlägg, samt CRUD-funktionerna för databashantering

Installera Mongoose

npm install mongoose

Uppkoppling till databas

const express = require("express");
const dotenv = require("dotenv");
const mongoose = require("mongoose");

// Ange sökvägen till vår .env-fil
dotenv.config({path: "./config.env"});

/* Hämta en miljövariabel 
   med process.env.VARIABELNAMN */
const port = process.env.PORT || 3000;

const DB = process.env.DATABASE.replace(
  "<PASSWORD>",
  process.env.DATABASE_PASSWORD
);

// Uppkoppling till databas
mongoose
.connect(DB, {
    useNewUrlParser: true,
    useCreateIndex: true,
    useFindAndModify: false
})
.then(function(con) {
    console.log(con.connecion);
    console.log("DB connection successful");
});
  
// Vår applikation startar en HTTP server och lyssnar på den port vi angivet
app.listen(port, function () {
  console.log(`Vår app lyssnar på port ${port}...`);
});

app.js

Skapa en modell för våra inlägg (posts)

const postSchema = new mongoose.Schema({
    title: String,
    image: String,
    body: String
});

const Post = mongoose.model("Post", postSchema);

Det som är bra med en NoSQL-databas som MongoDB är att du kan ändra egenskaperna i modellen i applikationen. Ex. Kanske vill vi lägga till ett datum då inlägget skapades, går även bra senare!

I det s.k schemat anger vi egenskaperna till ett inlägg. och sedan lägger in det som en modell. Vi kommer sedan använda Post för att läsa/skapa till databas.

Modellen läggs även den i egen fil

const mongoose = require("mongoose");

const postSchema = new mongoose.Schema({
    title: String,
    image: String,
    body: String
});

const Post = mongoose.model("Post", postSchema);

module.exports = Post;
const Post = require("./../models/postModel");

postModel.js

postController.js

Mongoosefunktioner för datapersistens

Databasoperation Hantering av inlägg Mongoosefunktion
Create  Skapa inlägg Model.create(request.body)
Read  Hämta alla inlägg Model.find()
Read Hämta specifikt inlägg Model.findById(request.params.id)
Update Uppdatera inlägg Model.findByIdAndUpdate(
request.params.id, request.body)
Delete Ta bort inlägg Model.findByIdAndDelete(request.params.id)
Edit Visa formulär för att uppdatera inlägg Model.findById(request.params.id)

Skapa ett inlägg i databasen

// Create - Skapa inlägg i databasen
exports.createPost = function (request, response) {

	/* Inlägget som kommer skickas från ett formulär 
           finns i request.body och sparas som en 
           Post-modell i vår databas */
        const newPost = Post.create(request.body);
        // Logga för att se inlägget som sparades
        console.log(newPost);
 
};

När man skickar data till en server (POST) så läggs det i request.body.

När datat skickas till server måste den tas om hand på rätt sätt. 

Därför måste denna finnas med i vår app.js:

app.use(express.json());

Hmm...spara till databas är ju nätverkstrafik! Vi gör funtkionen asynkron!

// Create - Skapa inlägg i databasen. Nu asykront!
exports.createPost = async function (request, response) {

        const newPost = await Post.create(request.body);

        console.log(newPost);
 
};

Skicka från POSTMAN

Verifiera i MongoDB Atlas

Hämta specifikt inlägg

// Create - Skapa inlägg i databasen
exports.getPost = function (request, response) {

		// Hämta specifikt inlägg utifrån id
         const post = await Post.findById(request.params.id);
        // Logga för att se inlägget som hämtades
        console.log(post);
 
};

När man skickar en url-parameter som ett id  hämtar man det i request.params.id.

Fixar du de övriga databasoperationerna?

Databasoperation Hantering av inlägg Mongoosefunktion
Create  Skapa inlägg Model.create(request.body)
Read  KVAR! Hämta alla inlägg Model.find()
Read  Hämta specifikt inlägg Model.findById(request.params.id)
Update KVAR! Uppdatera inlägg Model.findByIdAndUpdate(
request.params.id, request.body)
Delete KVAR! Ta bort inlägg Model.findByIdAndDelete(request.params.id)
Edit KVAR! Visa formulär för att uppdatera inlägg Model.findById(request.params.id)
Made with Slides.com