Webszerverek üzemeltetése: Forever, Statikus webszerverek, Express static.
Webszerverek és típusaik
- HTTP szerver- weboldalakat szolgáltat (HTTP protokoll segítségével)
- FTP szerver - fájlokat tölthetünk fel és le (FTP protokoll segítségével)
- Email szerver - továbbítja és tárolja az email üzeneteket
- Adatbázis szerver - az adott weboldallal kapcsolatban (például webshop) egy előre meghatározott struktúrában tárolja és szolgáltatja az adatokat (például felhasználói profil és vásárolt termékek)
A következő lépésként importáljuk be a http modult és adjuk értékül a http változónak. Hozzunk létre egy port nevű változót és állítsuk be neki a 3000 értéket. Hozzunk létre egy server nevű változót, hívjuk meg a http modul createServer() metódusát, melynek segítségével létrehozhatunk egy szervert. A szerver a bejövő "request" kérésre figyelje az on metódus meghívására. Erre reagáljon. Az argumentumba definiáljunk egy függvényt, request és response paraméterekkel. A request és response a bejövő kérésnek és a válasznak szánt objektumok. Egy ilyen válasz objektum többek között áll egy fej és egy törzs részből. A fej részében definiálhatjuk a válaszunk természetét (hibakód, formátum, stb...). A törzs szekcióban pedig a tényleges választ deklarálhatjuk. A response objektum fej részében ezen kívűl allítsuk be a karakterkódolást UTF-8-ra. Amennyiben készen állunk a válasz definiálásával, az end() metódust meghívva elküldhetjük azt. Legyen az üzenet jellege szöveges és maga az üzenet legyen az, hogy Válasz a szervertől. Visszatérve a parancssorhoz, futtassuk le a node server.js parancs segítségével a szerverünket. Nyissük meg egy böngészőt és írjuk a keresőbe azt, hogy http://localhost:3000 és várjunk az eredményre. Leállítani a ctrl + c billentyűkombinációval tehetjük meg. A példa itt próbálható ki.
// server.js
const http = require("http");
const port = 3000;
const server = http.createServer();
server.on("request", (request, response) => {
request.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
response.write("Válasz a szervertől");
response.end();
});
server.listen(port);
Forever
Express static
// server.js
const express = require('express');
const app = express();
const port = 3000;
// egy példa a public mappa tartalmának közzé tételére
app.use(express.static('public'));
// egy példa több mappa tartalmának közzé tételére
app.use(express.static('files1'));
app.use(express.static('files2'));
// egy példa virtuális útvonal implementálására, abszolút útvonallal
app.use('/static', express.static(path.join(__dirname, 'public')));
app.listen(port,(req,res)=>{
console.log(`a szerverünk a ${port} porton fut`);
});
MVC
Az MVC a Model View Controller szavakból összetevődő kifejezés egy rendkívül népszerű szoftvertervezési mintára. Egy webfejlesztő szemszögéből nézve az eltérő nyelvek esetén nincs két egyforma megvalósítási forma, sok programozó szerint igazi MVC nem is értelmezhető a webfejlesztésben. Az általános koncepciója az, hogy elválasszuk egymástól a funkcionalitást, a vezérlést, a felhasználói felületet, stb. az alkalmazásunkban. Ez megadja a lehetőséget, hogy fejlesztőket csoportosítsunk egyetlen problémára. Az egyetlen hátránya az adatok megfelelő struktúrájának tervezésének és implementálásának időigényességéből adódik. A Model az adatok manipulásásáért felel, alapvetően az alkalmazásunk agyaként funkcionál (az üzleti logikát megvalósító réteg). A Model feladata az, hogy és leírjuk és definiáljuk azokat a szabályokat, melyek alapján elérhetjük azokat. Általában kapcsolatban áll valamilyen típusú adatbázissal (NoSQL vagy SQL) és intézi a lekérdezéseket. Továbbá kapcsolatot tart fent a Controller-el azon keresztül, hogy az is lekérhet adatokat a Model-en keresztül, hogy frissítse a View-t. Az MVC View része az alkalmazásunk kinézetéért / felhasználói felületéért felel. A View definíció szerint HTML, CSS a Controller-től származó dinamikusan változó adatok összessége. Elhatárolódik egymástól a megjelenítés az adatszerkezetektől. Az adatokat kizárólag a Model osztályainak példányain keresztül (az objektum-orientált programozási környezetben) érhetjük el. Az összes View irányítását egy Modellel is meg lehet oldani . Az éppen használt keretrendszertől függően, a template engine eltérhet, ami a dinamikus átvitelért és megjelenítésért felel. Színtiszta HTML-el dolgozva a felhasználói oldalon a megjelenítésünk jellege statikus, dinamikusan változó adatokat nem lehet megjeleníteni. Template engine használatával megoldódik ez a problémánk. Végezetül maradt a Controller, ami összefoglalóan a bemeneti eszközök és csatornák felügyeletéért felel, lényegében összeköti őket. Ez azt az esetet is takarhatja, amikor egy felhasználó egy oldalt meglátogat és rákattintva egy linkre kérést indítványoz. Természetesen egy böngészőből nem indítható akármilyen kérés. Mint már tudjuk, a Controller egyfajta köztes állomásként viselkedik a Model és a View között. A Controller megkéri a Model-t arra, hogy adatot kérdezzen le az adatbázisból, ezt követően fogja az adatokat és betöltjük a View-be a template engine számára.
- Model
- Adat vezérelt logika
- Interakció az adatbázissal (SELECT, INSERT, UPDATE, DELETE)
- Kommunikáció a Controller-el
- Keretrendszertől függően képes frissíteni a View-t
- View
- A felület, amivel a felhasználó találkozik
- Általában HTML és CSS elemekből épül fel
- Kapcsolatot tart fenn a Controller-el
- A Controller-ből dinamikus adatok tölthetőek be
- Template engine
- Controller
- Bemenet
- Bejövő kéréseket dolgoz fel (GET, POST, PUT, DELETE)
- A Model-től kér le adatokat
- A View számára adatokat továbbít
![](../MVC.jpg)
Middleware függvények, hibakezelés
A Middleware függvények definíció szerint olyan függvények, amik hozzáférnek a request (kérés - req) és response (válasz - res) objektumokhoz és kezelik azokat. Az egyes kérésekhez feltételeket is köthetünk, ekkor jön aképbe a next() middleware függvény. Amennyiben a definiált feltétel teljesül az egyik feltételre, átugrik a soron következő kérésre. Akkor is szokás használni, ha egy idő után nem hajlandó leállni a kérés-válasz ciklus. Továbbá rendelkezik egy harmadik argumentummal, ahova függvény vár ami meghívódik amint lefut a Middleware kódunk. Ez azt jelenti, hogy megvárja amíg mondjuk egy aszinkron művelet (adat lekérése az adatbázisból) megtörténik és csak aztán teszi meg a következő lépést. Az Express middleware-ek közül a legfontosabbakat kiemelve:
- Application level (alkalmazás szintű) middleware: app.use
- Router level (útvonal szintű) middleware: router.use
- Built-in (beépített) middleware: express.static
- Error-handling (hibakezelés): app.use(err,req,res,next)
- Third-party (harmadik féltől származó) middleware: bodyparser, cors
![](../MIDDLEWARE1.jpg)
Az Express-ben lehetőségünk van a hibakezelő middleware függvéynek implementálására. A szokásos middleware függvényekkel ellentétben nem három, hanem négy paramétert várnak az argumentumukban.
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Valamilyen hiba történt a szerverrel!');
});
Routing (get, post, put, del, all)
Tegyük fel, hogy számos útvonallal rendelkezünk és minden egyes útvonallal valamilyen erőforrást és / vagy nézetet kívánnánk elérni. Továbbá arról is meg szeretnénk győzödni arról, hogy az egyes útvonalakhoz csakis a megfelelő személyek férjenek hozzá. Ebben az esetben egy autentikációs middleware-t kell megvalósítanunk. Amint az autentikáció feltétele teljesül, az erőforráshoz való hozzáférést biztosítsuk a next() meghívásával. Amennyiben az autentikáció sikertelen, a next() meghívása helyett hibával térjünk vissza. Valósítsuk meg az elképzelésünket és lássuk mi lesz az eredmény! A példa itt próbálható ki.
![](../MIDDLEWARE2.jpg)
// server.js
const express = require('express');
const app = express();
const port = 3000;
const bejelentkezés = (req,res,next) =>{
console.log(`Bejelentkezve ${req.url} ${req.method}`);
next();
};
app.use(bejelentkezés);
app.get('/felhasznalok',(req,res)=>{
res.json({
'status':true
})
})
app.post('/mentes',(req,res)=>{
res.json({
'status':true
})
})
app.listen(port,(req,res)=>{
console.log('a szerverünk a ${port} porton fut');
});
// server.js
const express = require('express');
const app = express();
const port = 3000;
const router = express.Router();
router.use((req,res,next)=>{
console.log("Idő:",new Date());
next();
});
router.get("/user/:id",(req,res,next)=>{
console.log('URL cím:', req.originalUrl);
next();
},(req,res,next)=>{
console.log('Kérés típusa:', req.method);
next();
},(req,res)=>{
res.json({
status:true,
id:req.params.id
})
})
app.use('/',router);
app.listen(port,(req,res)=>{
console.log(`a szerverünk a ${port} porton fut`);
});
Példa alkalmazás
Az eddig tanultakat felhasználva Írjunk egy egyszerű szerver által szolgáltatott alkalmazást Express segítségével. A feladat az lenne, hogy nyilván tartsunk néhány hallgató nevét és az általuk felvett tárgyait. Az egyszerűség kedvéért az adatok nyilván tartását reprezentáljuk egy objektummal, melyek tulajdonságaihoz egy-egy objektum van rendelve. Ezek egy-egy hallgatót reprezentálnak, melyekben el van tárolva a név, illetve a felvett tárgyak listája. A feladat lényegében az lenne, hogy a böngészőnkön annyi nézet jelenítődhessen meg, ahágy hallgató van és minden egyes nézetben írjuk ki a hallgató nevét, azonosítóját, illetve a felvett tárgyait. A példa itt próbálható ki.
// server.js
const express = require('express');
const app = express();
const port = 3000;
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.set("views", __dirname + "/views");
const hallgatok = {
1: {
nev: 'Gábor Tibor',
felvett_targyak: ['c++', 'java', 'python']
},
2: {
nev: 'Lajkó Dénes',
felvett_targyak: ['c', 'javascript', 'python']
},
3: {
nev: 'Nagy János',
felvett_targyak: ['mysql', 'java', 'mongodb']
}
};
app.get('/hallgatok/:id',
(req, res) => {
res.render(
'hallgatok',
{
nev: hallgatok[Number(req.params.id)].nev,
id: req.params.id,
felvett_targyak: hallgatok[Number(req.params.id)].felvett_targyak
}
)
}
);
app.listen(port, () => { console.log(`a szerverünk a ${port} porton fut`)});
server.js
package.json
package-lock.json
> node_modules
> views
|_ hallgatok.ejs
// hallgatok.ejs
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="utf-8">
<title>Hallgatók listája</title>
<style>
</style>
</head>
<body>
<p>Hallgató neve: <%= nev %></p>
<p>Azonosito: <%= id %></p>
<p>Felvett tárgyak:</p>
<ul>
<% felvett_targyak.forEach((targy) => { %>
<li> <%= targy %></li>
<%});%>
</ul>
</body>
<html>
Irodalomjegyzék
[1] | Vue.js core team. Vue.js: The Progressive JavaScript Framework. https://vuejs.org, Legutóbb megtekintve: 2019. április 22. |
[2] | Vue.js core team. API, Global Config, directive. https://vuex.vuejs.org/vuex.png, Legutóbb megtekintve: 2019. április 22. |
[3] | Vue.js core team. API, Global Config, computed. https://vuejs.org/v2/api/#computed, Legutóbb megtekintve: 2019. április 22. |
[4] | Vue.js core team. API, Global Config, components. https://vuejs.org/v2/api/#components, Legutóbb megtekintve: 2019. április 22. |
[5] | Vue.js core team. Vue-CLI. https://cli.vuejs.org/guide/creating-a-project.html#vue-create, Legutóbb megtekintve: 2019. április 22. |
[6] | Vue.js core team. Vue-router. https://router.vuejs.org/guide/#html, Legutóbb megtekintve: 2019. április 22. |
[7] | Vue.js core team. Render Functions and JSX. https://vuejs.org/v2/guide/render-function.html, Legutóbb megtekintve: 2019. április 22. |
[8] | w3schools core team. JavaScript RegExp Reference. https://www.w3schools.com/jsref/jsref_obj_regexp.asp, Legutóbb megtekintve: 2019. április 22. |
[9] | Google Chrome DevTools core team. Chrome DevTools. https://developers.google.com/web/tools/chrome-devtools, Legutóbb megtekintve: 2019. április 22. |
[10] | Node.js core team. Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. https://nodejs.org/en/, Legutóbb megtekintve: 2019. április 22. |
[11] | NPMJS core team. NPMJS. https://www.npmjs.com, Legutóbb megtekintve: 2019. április 22. |
[12] | ExpressJS core team. Express Fast, unopinionated, minimalist web framework for Node.js. https://expressjs.com, Legutóbb megtekintve: 2019. április 22. |
[13] | EJS core team. EJS: Embedded JavaScript templating. https://ejs.co, Legutóbb megtekintve: 2019. április 22. |
[14] | Olga Filipova. Learning Vue.js 2. Packt Publishing Ltd., Livery Place, 35 Livery Street, Birmingham, B3 2PB, UK, 3, 2016. |
[15] | E.F. Codd. A relational Model of Data for Large Shared Data Banks. Communications of the ACM, 13 (6) 1970. |
[16] | Papp Edit. Adatbáziskezelés. Booklands 2000 Könyvkiadó Kft., 5600 Békéscsaba, Dr. Becsey Oszkár u. 42., 1, 2004. |
[17] | Nemzeti Szakképzési és Felnőttképzési hivatal. Szoftverfejlesztő tanfolyam. https://www.nive.hu, Legutóbb megtekintve: 2019. április 22. |
[18] | JavaScript.info core team. JavaScript.info. https://javascript.info/promise-basics, Legutóbb megtekintve: 2019. április 22. |
[19] | Craig Buckler. Sitepoint (JavaScript) - Understanding ES6 Modules. https://www.sitepoint.com/understanding-es6-modules/, Legutóbb megtekintve: 2019. április 22. |