EAN Stack - Node.js, Express.js 1/61 MEAN Stack - Node.js, Express.js Technologie zarządzania treścią dr inż. Robert Perliński rperlinski@icis.pcz.pl Politechnika Częstochowska Instytut Informatyki Teoretycznej i Stosowanej 11 października 2017
MEAN Stack - Node.js, Express.js 2/61 Kwestie organizacyjne Kontakt: mail: rperlinski@icis.pcz.pl strona: http://icis.pcz.pl/~rperlinski konsultacje: środa 13:00-16:00 (najlepiej po wcześniejszym umówieniu drogą mailową)
MEAN Stack - Node.js, Express.js 3/61 Plan wykładu 1 MEAN stack - krótkie wprowadzenie w Node.js 2 Wprowadzenie do baz danych NoSLQ 3 Bazy danych klucz-wartość 4 Redis 5 Bazy danych dokumentów 6 MongoDB - wprowadzenie, JSON 7 MongoDB - grupowanie, operatory agregacji 8 MongoDB - indeksy 9 Bazy grafowe 10 Neo4j - część 1 11 Neo4j - część 2 12 Bazy rodziny kolumn 13 Cassandra - część 1 14 Cassandra - część 2 15 XML i technologie pochodne
MEAN Stack - Node.js, Express.js 4/61 Literatura Pramod J. Sadlage, Martin Folwer, NoSQL Kompendium wiedzy, Helion, 2015 Dan Sulivan, NoSQL Przyjazny przewodnik, Helion 2016 K. Banker, P. Bakkum, S. Verch, D. Garrett, T. Hawkins, MongoDB w akcji, Helion 2017 Karl Seguin, The Little Redis Book, 2012, http://openmymind.net/redis.pdf Karl Seguin, The Little MongoDB Book, 2011, http://openmymind.net/mongodb.pdf P. Kazienko, K. Gwiazda, XML na poważnie, Helion 2002
MEAN Stack - Node.js, Express.js 5/61 Dokumentacja online Bazy NoSQL: http://redis.io/documentation https://docs.mongodb.com/manual/ http://cassandra.apache.org/doc/latest/ https://neo4j.com/developer/ Node.js, Express.js i NPM: https://nodejs.org/en/docs/ http://expressjs.com/ https://www.npmjs.com/ Formaty danych: http://json.org/ https://www.w3.org/xml/
MEAN Stack - Node.js, Express.js 6/61 Plan wykładu 1 Wprowadzenie do MEAN Stack 2 Node.js npm wywołania zwrotne 3 Express.js obsługa formularzy, GET i POST przesyłanie plików REST API 4 Źródła
MEAN Stack MEAN Stack - Node.js, Express.js 7/61
MEAN Stack - Node.js, Express.js 8/61 MEAN Stack MongoDB darmowa, otwarta baza NoSQL, przechowuje dokumenty w formacie JSON (BSON), dostarcza wsłasny język zapytań, Express.js framework JavaScript wspierający tworzenie aplikacji MVC po stronie serwera, pozwala użytkownikom tworzyć trasy (routes) i wykorzystywać szablony, Angular.js otwarty framework JavsScript wykorzystujący MVC do tworzenia aplikacji internetowych działających po stronie klienta w technologi SPA, wspierany i firmowany przez Google, obecnie występuje w dwóch zupełnie odmiennych wersjach (1.6.6 i 4.4.4), Node.js środowisko JavaScript obsługujące operacje wejścia/wyjścia sterowane zdarzeniami, działające po stronie serwera, bazujące na silniku Google V8.
MEAN Stack MEAN Stack - Node.js, Express.js 9/61
MEAN Stack - Node.js, Express.js 10/61 Zalety MEAN Stack Jeden język do wszystkiego - cały zespół używa tylko JavaScript (na serwerze jak i po stronie klienta), obiekty JavaScript po prostu zapisujemy w MongoDB. Można uruchomić niemal na każdym urządzeniu czy platformie - duża przenośność kodu. Technologia ta jest prawie zupełnie darmowa. Bardzo dobre wsparcie dla przetwarzania w chmurze czy pojedynczych funkcjonalności jako usług sieciowych, np. baz danych NoSQL (compose.com czy mongolab.com). Można łatwo wykorzystać dostępne usługi hostingowe, np. https://www.heroku.com.
MEAN Stack - Node.js, Express.js 11/61 Node.js https://nodejs.org/en/ platforma działająca po stronie serwera na bazie silnika Google Chrome V8, zaprojektowany przez Ryana Dahl w 2009 roku, ma służyć prostemu tworzeniu szybkich i skalowalnych aplikacji internetowych, open source, całkowicie darmowe, aplikacje napisane w Node.js działają na OS X, MS Windows i Linux ie, używane przez tysiące programistów na całym świecie. /* Program Hello World w Node.js */ console.log("hello World!");
MEAN Stack - Node.js, Express.js 12/61 Node.js zalecany do tworzenia aplikacji: z dużą liczbą operacji wejścia/wyjścia, strumieniowania danych, np. video, Single Page Applications (SPA), udostępniających API w formacie JSON, z intensywną wymianą danych w czasie rzeczywistym na wielu urządzeniach, np. portale społecznościowe, nie zalecany przy aplikacjach intensywnie wykorzystujących procesor (CPU), npm - system pakietów Node.js - największy zbiór bibliotek open source na świecie (ponad 330000) łatwa produkcja aplikacji internetowych, Node.js = środowisko uruchomieniowe + biblioteki JavaScript wykorzystuje biblioteki libuv
MEAN Stack - Node.js, Express.js 13/61 Cechy Node.js Asynchroniczność i sterowanie zdarzeniami Serwer wywołuje kolejne API, jedno po drugim. Nie czeka na zakończenie wywołanej funkcji aby zwrócić dane. Za wszystko odpowiada mechanizm obsługi zdarzeń. Duża szybkość - silnik Chrome V8 zapewnia dużą szybkość w wykonywaniu kodu. Jednowątkowość z zachowaniem dużej skalowalności Node.js używa modelu jednowątkowego z pętlą zdarzeń. Potrafi obsłużyć znacznie więcej żądań niż tradycyjne serwery (np. Apache). Mechanizm zdarzeń pomaga serwerowi na udzielanie odpowiedzi w sposób nieblokujący, pozwala to na wysoką skalowalność. W klasycznych serwerach jest tworzona ograniczona liczba wątków obsługujących żądania. Licencja - Node.js jest tworzony na licencji MIT. Projekty, aplikacjie, firmy - długa lista wykorzystywania Node.js: ebay, General Electric, GoDaddy, Microsoft, PayPal, Uber, Wikipins, Yahoo, Yammer...
MEAN Stack - Node.js, Express.js 14/61 libuv https://github.com/libuv/libuv międzyplatformowa biblioteka skupiająca się na asynchronicznych operacjach wejścia/wyjścia, stworzona pierwotnie dla Node.js, używana obecnie przez: Luvit, Julia, pyuv i inne, niektóre cechy: wydajna pętla obsługująca zdarzenia, asynchroniczna obsługa gniazd TCP i UDP, asynchroniczna obsługa plików i systemu plików, obsługa sygnałów, obsługa zdarzeń systemu plików, zegar wysokiej rozdzielczości
MEAN Stack - Node.js, Express.js 15/61 Najważniejsze części Node.js Najważniejsze części Node.js przedstawiono na rysunku:
MEAN Stack - Node.js, Express.js 16/61 Dokumentacja Node.js, v8.6.0 Assertion Testing Async Hooks Buffer C++ Addons C/C++ Addons - N-API Child Processes Cluster Command Line Options Console Crypto Debugger Deprecated APIs DNS Domain ECMAScript Modules Errors Events File System Globals HTTP HTTP/2 HTTPS Inspector Internationalization Modules Net OS Path Performance Hooks Process Punycode Query Strings Readline REPL Stream String Decoder Timers TLS/SSL Tracing TTY UDP/Datagram URL Utilities V8 VM ZLIB
MEAN Stack - Node.js, Express.js 17/61 Obiekty globalne w Node.js Obiekty globalne w Node.js są dostępne we wszystkich modułach, nie trzeba ich w żaden sposób dołączać. filename - nazwa pliku, którego kod jest wykonywany, zawra całą ścieżkę, dirname - nazwa katalogu wraz z całą ścieżką, w którym znajduje się wykonywany plik, settimeout(cb, ms) - uruchamianie funkcji zwrotniej po określonej liczbie ms, cleartimeout(t) - zatrzymywanie licznika czasu utworzonego wcześniej funkcją settimeout(), setinterval(cb, ms) -uruchamianie funkcji zwrotnej co określoną liczbę ms. function printhello(){ console.log( "Hello, World!"); } // Wywołanie funkcji po upływie 2 s var t = settimeout(printhello, 2000); // Usunięcie licznika czasu cleartimeout(t);
MEAN Stack - Node.js, Express.js 18/61 Obiekty globalne w Node.js Inne często wykorzystywane obiekty globalne to: console - drukowanie wiadomości w różnych poziomach błędu na stdout albo stderr, zawiera metody: log(), info(), warn(), error(), dir(), trace(), assert() - wyświetlanie wiadomości informacyjnych w różny sposób, console.time(label) - zapamiętuje punkt czasowy związany z etykietą, console.timeend(label) - koniec przedziału czasowego z wiązanego z podaną etykietą, wyświetla przedział czasu, process - obiekt może emitować następujące zdarzenia: exit - emitowane tuż przed zakończeniem procesu, beforeexit - emitowane kiedy Node opróżnił już pętle zdarzeń i nie ma innych zadań, uncaughtexception - emitowane, kiedy eskalacja wyjątków wróci aż do pętli zdarzeń, zdarzenia konkretnych sygnałów - emitowane, kiedy system otrzyma konkretne zdarzenia, np. SIGINT, SIGHUP,... Procesy mają też szereg użytecznych właściwości: stdout, stderr, stdin, argv, execpath, execargv, env, exitcode, version, versions, config, pid, title, arch, platform, mainmodule, metod: abort(), chdir(directory), cwd(), exit([code]), getgid(), setgid(id), getuid(), setuid(id), getgroups(), setgroups(groups), initgroups(user, extra group), kill(pid[, signal]), memoryusage(), nexttick(callback), umask([mask]), uptime(), hrtime().
MEAN Stack - Node.js, Express.js 19/61 Użyteczne moduły w Node.js Najbardziej powszechnie i często używane moduły Node.js: moduł os (Operating System) - podstawowe infomacje związane z systemem operacyjnym (pamięć, procesor,...) moduł path - przechowywanie i przetwarzanie ścieżek plików i katalogów, moduł net - pozwala na tworzenie zarówno serwerów jak i klientów, łączenie się, przesyłanie informacji w postaci strumieniowej, moduł dns - pozwala na obsługę DNS (sprawdanie adresów, różne typy adresów DNS, kody błędów), moduł domain - pozwala na wychwytywanie nieobsłużonych błędów. var os = require("os"); console.log('endianness : ' + os.endianness()); console.log('type : ' + os.type()); console.log('platform : ' + os.platform()); console.log('total memory : ' + os.totalmem() + " bytes."); console.log('free memory : ' + os.freemem() + " bytes."); endianness : LE type : Linux platform : linux total memory : 8110882816 bytes. free memory : 4815204352 bytes.
MEAN Stack - Node.js, Express.js 20/61 REPL Terminal Read Eval Print Loop (REPL) - środowisko komputerowe, np. Linux Shell, w którym polecenia są automatycznie przetwarzane i wyniki są wyświetlane w trybi interakcyjnym. Node.js też ma takie środowisko: Read - wczytuje dane od użytkownika, parsuje do struktur JavaScript i przechowuje w pamięci, Eval - bierze wprowadzone dane i je oblicza, wyznacza wartości, Print - wyświetla wyniki, Loop - trzy powyższe przetwarza w pęltli aż do dwukrotnego nacieśnięcia Ctrl+c. $ node > 1 + ( 2 * 3 ) - 4 3 > a = 12 // zachowane w zmiennej i wyswietlone 12 > var b = 12 // zachowane w zmiennej ale nie wyswietlone (var) undefined > (a+b)*2 48 > console.log(a+b) 24 undefined
MEAN Stack - Node.js, Express.js 21/61 REPL Terminal - wiele linii i mamy możliwość pisania wyrażeń składających się z wielu linii, symbol podkreślenia ( ) zwraca ostatni wynik: > x = 5 5 > while(x>0) {... --x;... console.log(x);... } 4 3 2 1 0 undefined > x+8 8 > _ 8
MEAN Stack - Node.js, Express.js 22/61 REPL Terminal - polecenia Ctrl+c - przerywanie aktualnego polecenia, Ctrl+c dwa razy - zamykanie Node REPL, Ctrl+d - zamykanie Node REPL, Klawisze Góra/Dół - historia polecenie, potrzednie/następne polecenie, klawisz Tab - lista aktualnych komend,.help - lista wszystkich komend,.break albo.clear - wyjście z wieloliniowego wyrażenia,.save nazwapliku - zapis sesji Node REPL do pliku,.load nazwapliku - wczytanie zawartości pliku do bieżącej sesji.
MEAN Stack - Node.js, Express.js 23/61 npm npm - menadżer pakietów dla node.js (dla JavaScript). zbiór pakietów/modułów dla Node.js dostępnych online: https://www.npmjs.com/ narzędzie do instalacji pakietów Node.js, zarządza wersjami i zależnościami pakietów Node.js dokumnetacja - https://docs.npmjs.com/ najczęściej instalowane pakiety: npm, express, less, browserify, pm2,... $ npm --version $ sudo npm install npm -g $ npm install <Nazwa Modułu> $ npm install express
MEAN Stack - Node.js, Express.js 24/61 npm - globalna i lokalna instalacja modułów Pakiety lokalne: domyślnie pakiety instalowane są lokalnie w katalogu node modules w folderze, w którym jest aplikacja Node.js, lokalne pakiety są dostępne poprzez metodę require(), lista lokalnych pakietów/modułów: npm ls. Pakiety globalne: globalne pakiety znajdują się w strukturze systemu plików komputera, nie można ich wczytać używając require(), instalacja pakietu globalnie: npm install express -g, lista globalnych pakietów: npm ls -g.
MEAN Stack - Node.js, Express.js 25/61 Tworzenie pakietu Tworzenie pakietu: npm init { } polecenie pyta o najważniejsze dane pakietu (proponując domyślne wartości), tworzony jest plik package.json, np.: "name": "rest", "version": "1.0.0", "description": "hello world restfull api", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "restfull" ], "author": "rperlinski", "license": "ISC"
MEAN Stack - Node.js, Express.js 26/61 Plik package.json package.json - plik odpowiedzialny za zarządzanie lokalnie zainstalowanymi pakietami: przechowuje informacje o zależnościach w naszym projekcie, pozwala określić wersje pakietów, których używa nasz projekt, pozwala na odtworzenie naszej aplikacji - łatwość w dzieleniu się naszym projektem Minimum pliku package.json to nazwa i wersja: { } "name": "moj-pakiet", "version": "1.0.0"
MEAN Stack - Node.js, Express.js 27/61 Tworzenie pakietu, instalacja Instalacja pakietów } mkdir rest; cd rest npm init - inicjalizacja, tworzy plik package.json npm install express, albo lepiej npm install --save express - dodaje zależności do pliku package.json:... "license": "ISC", "dependencies": { "express": "^4.13.4" }
MEAN Stack - Node.js, Express.js 28/61 Atrybuty w pliku package.json name - nazwa pakietu, atrybut obowiązkowy, tylko małe litery, jedno słowo - nie ma spacji, dopuszczalne myślniki (-) i podkreślenia ( ), version - wersja pakietu, atrybut obowiązkowy, description - opis pakietu, homepage - strona domowa pakietu, author - autor pakietu, contributors - współautorzy pakietu, dependencies - lista zależności, npm automatycznie instaluje wszystkie podane zależności w katalogu node modules naszego pakietu, repository - typ repozytorium i URL pakietu, main - punkt wejściowy pakietu, keywords - słowa kluczowe.
MEAN Stack - Node.js, Express.js 29/61 Inne polecenia npm npm uninstall express - odinstalowanie modułu express, npm update express - wywoływane po zmianach w pliku package.json, autoamtycznie aktualizuje zależności, npm search express - wyszukiwanie pakietów korzystając z polecenia npm, npm init - generowanie pliku package.json co tworzy nowy moduł/pakiet, npm adduser - dodanie użytkownika do repozytorium npm (nazwa i poprawny email) i następnie można... npm publish - publikowanie naszego pakietu, będzie można go instalować poleceniem npm install :)
MEAN Stack - Node.js, Express.js 30/61 Wywołania zwrotne I Wywołanie zwrotne (ang. callback) - technika programowania będąca odwrotnością wywołania funkcji. Użytkownik rejestruje funkcję do późniejszego wywołania. Funkcje biblioteki wywołają ją w stosownym czasie. Zwykle to programista sam wywołuje funkcje dostarczane przez bibliotekę. Wywołanie zwrotnie: asynchroniczny odpowiednik funkcji, jest wykonywane kiedy zakończy się pewne zadanie, kawałek wykonywalnego kodu, który przekazywany jako argument do innego kodu, od którego oczekujemy, że wywoła przekazany kod w odpowiednim czasie. Node używa tego bardzo intensywnie. Duża część API do Node jest tak napisana, aby wspierać wywołania zwrotne.
MEAN Stack - Node.js, Express.js 31/61 Wywołania zwrotne II Programy z funkcjami synchronicznymi: wykonują się sekwencyjnie, z punktu widzenia programisty łatwiej implementować logikę aplikacji. Programy działające asynchronicznie: nie wykonują się sekwencyjnie, jeśli fragment kodu potrzebuje określonych danych powinien być umieszczony w tym samym bloku kodu, żeby wykonanie tych zależnych od siebie instrukcji było sekwencyjne.
MEAN Stack - Node.js, Express.js 32/61 Wywołania zwrotne na przykładzie Odczyt z pliku może być: synchroniczny - czekamy na zwrócenie danych zawartych w pliku, asynchroniczny: funkcja zaczyna czytać plik ale... od razu zwraca sterowanie, wykonywane są kolejne instrukcje; zakończenie odczytywania danych z pliku wykonuje wywołanie zwrotne, jako parametr przekazywana jest zawartość pliku, nie ma tutaj blokowania. Wniosek: wysoka skalowalność Node.js (nawet 1 mln żądań na sekundę), przetwarzanie dużej liczby żądań bez oczekiwania na zwrócone wyniki.
Podwójne API Node.js File System - metody asynchroniczne fs.access(path[, mode], callback) fs.close(fd, callback) fs.exists(path, callback) fs.read(fd, buffer, offset, length, position, callback) fs.unlink(path, callback)... File System - metody synchroniczne fs.accesssync(path[, mode]) fs.closesync(fd) fs.existssync(path) fs.readsync(fd, buffer, offset, length, position) fs.unlinksync(path)... MEAN Stack - Node.js, Express.js 33/61
MEAN Stack - Node.js, Express.js 34/61 Wywołania zwrotne - odczyt z pliku, przykład wywołanie synchroniczne var fs = require("fs"); var data = fs.readfilesync('dane.txt'); console.log(data.tostring()); console.log("koniec programu"); Litwo, Ojczyzno moja! ty jesteś jak zdrowie; Ile cię trzeba cenić, ten tylko się dowie,... Koniec programu wywołanie asynchroniczne var fs = require("fs"); fs.readfile('dane.txt', function (err, data) { if (err) return console.error(err); console.log(data.tostring()); }); console.log("koniec programu"); Koniec programu Litwo, Ojczyzno moja! ty jesteś jak zdrowie; Ile cię trzeba cenić, ten tylko się dowie,...
MEAN Stack - Node.js, Express.js 35/61 Pierwszy projekt w Node.js Większość aplikacji Node.js składa się z 3 części: import wymaganych modułów - używa się dyrektywy require, utworzenie serwera - serwer będzie oczekiwał na żadania klientów i zwracał odpowiedzi, odczytywanie żądań i zwracanie odpowiedzi - podstawowe działanie serwera. var http = require("http"); var server = http.createserver(function (request, response) { // Wysyłanie nagłówków protokołu HTTP // Status HTTP: 200 : OK, Content Type: text/plain response.writehead(200, {'Content-Type': 'text/plain'}); // Wysyłanie ciała odpowiedzi, niezależnie od rodzaju żądania response.end('pierwszy projekt w Node.js\n'); }); server.listen(5000); console.log('server działa na http://127.0.0.1:5000/');
MEAN Stack - Node.js, Express.js 36/61 Serwer sieciowy Serwer sieciowy: aplikacja obsługująca żądania HTTP przesyłane od klientów, np. przeglądarki, w odpowiedzi zwracająca strony internetowe, zwykle dostarczane są dokumenty HTML razem z obrazkami, stylami CSS i skryptami, większość serwerów obsługuje skrypty po stronie serwera w jednym z wielu języków, serwery wykonują określone zadania, pobierają dane z bazy, przetwarzają skomplikowaną logikę... przykładem może być serwer Apache.
MEAN Stack - Node.js, Express.js 37/61 Architektura aplikacji internetowej Klasyczny podział aplikacji internetowej na cztery warstwy: Klient - przeglądarki internetowe (w tym z urządzeń mobilnych) i aplikacje wykonujące żądania HTTP, Serwer internetowy - przechwytuje żadania od klientów i zwraca im odpowiedzi, Warstwa biznesowa - zawiera aplikację serwerową wykorzystywaną przez serwer internetowy; komunikuje się z warstwą danych, Dane - zawiera dane w bazie danych albo dostępnych z innego źródła.
MEAN Stack - Node.js, Express.js 38/61 Tworzenie serwera z użyciem Node.js i http var http = require('http'); var fs = require('fs'); var url = require('url'); http.createserver( function (request, response) { // Parsuje żądanie zawierające nazwę pliku var pathname = url.parse(request.url).pathname; // Wyświetlanie nazwy pliku, którego dotyczyło żądanie console.log("request for " + pathname + " received."); fs.readfile(pathname.substr(1), function (err, data) { if (err) { console.log(err); response.writehead(404, {'Content-Type': 'text/html'}); } else { response.writehead(200, {'Content-Type': 'text/html'}); response.write(data.tostring()); // zwracanie treści wybranego pliku } response.end(); // wysyłanie odpowiedzi }); }).listen(5000); console.log('serwer uruchomiony na http://127.0.0.1:5000/');
MEAN Stack - Node.js, Express.js 39/61 Tworzenie serwera z użyciem Node.js index.html <html> <head> <title>pierwszy projekt</title> </head> <body> Pierwszy projekt w Node.js </body> </html> $ node server.js Serwer uruchomiony na http://127.0.0.1:5000/ Otwieramy w przeglądarce: http://localhost:5000/index.html Narzędzie forever pozwala na wygodniejszą pracę, automatycznie przeładowuje serwer po zmianach, instalacja: sudo npm install -g forever Uruchomienie serwera: forever -w server.js
MEAN Stack - Node.js, Express.js 40/61 Tworzenie klienta z użyciem Node.js i http var http = require('http'); // Opcje użyte w żądaniu var options = { host: 'localhost', port: '5000', path: '/index.html' }; // Funkcja zwrotna obsługująca zwrócone dane var callback = function(response){ // Dopisywanie napływających danych do strunienia var body = ''; response.on('data', function(data) { body += data; }); response.on('end', function() { // Wypisanie danych po ich otrzymaniu w pełni console.log(body); }); } // Wysłanie żądania do seerwera var req = http.request(options, callback); req.end();
MEAN Stack - Node.js, Express.js 41/61 Tworzenie klienta z użyciem Node.js Wywołanie aplikacji klienta w innym terminalu, wynik działania: $ node client.js <html> <head> <title>pierwszy projekt</title> </head> <body> Pierwszy projekt w Node.js </body> </html>
MEAN Stack - Node.js, Express.js 42/61 Express http://expressjs.com/ Express to szybki, elastyczny (nie wymuszający konkretnych rozwiązań), minimalistyczny szablon aplikacji internetowych i mobilnych dla Node.js. Express: udostępnia solidną funkcjonalność do budowania aplikacji, pozwala na szybkie budowanie aplikacji bazujących na Node.js, pozwala na utworzenie warstw pośredniczących odpowiadających na żądania HTTP, dostarcza mechanizm trasowania (ang. routing) - różne akcje dla różnych metod i adresów URL, pozwala na dynamiczne renderowanie stron HTML poprzez przekazywanie argumentów do szablonów.
MEAN Stack - Node.js, Express.js 43/61 ExpressJS i warstwy pośrednie Instalacja: npm install express ExpressJS to komplenty framework. Działa z szablonami (jade, ejs, handlebars, hogan.js) i kompilatorami CSS (less, stylus, compass). Dzięki wartstwom pośredniczącym (oprogramowanie pośredniczące) obsługuje również: ciasteczka, sesje, buforowanie, CSRF, kompresję i wiele innych. Oprogramowanie pośredniczące: łańcuch/stos programów przetwarzających każde żądanie do serwera. Takich programów w stosie może być dowolna liczba, przetwarzanie odbywa się jeden po drugim. Niektóre z nich mogą zmieniać żądanie, tworzyć logi czy inne dane, przekazywać je do następnych (next()) programów w strumieniu.
MEAN Stack - Node.js, Express.js 44/61 Express-middlewares Warstwy pośredniczące dodajemy do ExpressJS używając app.use dla dowolnej metody albo app.verb (np. app.get, app.delete, app.post, app.update,...)
MEAN Stack - Node.js, Express.js 45/61 Express - instalacja $ npm install express --save Inne ważne moduły, które warto od razu zainstalować: body-parser - warstwa pośrednia obsługująca JSON, Raw, Text i dane formularza przekazane w URL, cookie-parser - przetwarza nagłówki ciasteczek (cookie header) i dodaje obiekt do req.cookies, w którym klucze to nazwy przesłanych ciasteczek, multer - warstwa pośrednia w Node.js do obsługi multipart/form-data (kodowanie danych z formularza).
MEAN Stack - Node.js, Express.js 46/61 Express, Hello World hello.js var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send('hello World'); }) var server = app.listen(5000, function () { var host = server.address().address var port = server.address().port console.log("przykładowa aplikacja nasłuchuje na http://%s:%s", host, port) }) Wynik: $ node hello.js Otwieramy w przeglądarce: http://localhost:5000/ Przykładowa aplikacja nasłuchuje na http://0.0.0.0:5000 Express używa funkcji zwrotnych z argumentami req i res (obiekty request i response), które zawierają bardzo dużo informacji i żądaniu i odpowiedzi.
MEAN Stack - Node.js, Express.js 47/61 Nagłówek protokołu HTTP W nagłówku http jest pole Content-Type, które określa, jakiego typu są przekazywane dane, np. text/html, application/json czy image/png. Lista formatów: http://www.iana.org/assignments/media-types/ media-types.xhtml Tworząc formularz określamy w jaki sposób będą zakodowane dane przez niego przesyłane. Pole enctype występujące w formularzu, ma trzy dopuszczalne wartości: application/x-www-form-urlencoded - dane tekstowe, bez plików, mała objętość, wartość domyślna, multipart/form-data - pliki, dane binarne, duża objętość, text/plain - tylko do debugowania, nie używane w produkcji.
MEAN Stack - Node.js, Express.js 48/61 Express, trasowanie I Reakcje na żądania użytkowników w punktach końcowych (URI, metody protokołu HTTP). var express = require('express'); var app = express(); app.get('/', function (req, res) { console.log("otrzymano żądanie GET dla strony głównej"); res.send('hello GET'); }) app.post('/', function (req, res) { console.log("otrzymano żądanie POST dla strony głównej"); res.send('hello POST'); }) app.delete('/usun', function (req, res) { console.log("otrzymano żądanie DELETE dla strony /usun"); res.send('hello DELETE'); }) app.get('/user_list', function (req, res) { console.log("otrzymano żądanie GET dla strony /user_list"); res.send('lista użytkowników'); }) app.get('/ab*cd', function(req, res) { // wzorzec strony: abcd, abxcd, ab123cd,... console.log("otrzymano żądanie GET dla strony /ab*cd"); res.send('wzorzec strony dopasowany'); }) var server = app.listen(5000, function () { var host = server.address().address var port = server.address().port console.log("przykładowa aplikacja nasłuchuje na http://%s:%s", host, port) })
MEAN Stack - Node.js, Express.js 49/61 Express, trasowanie II Kolejne żądania: GET - http://localhost:5000/ // Hello GET POST - http://localhost:5000 // Hello POST DELETE - http://localhost:5000/usun // Hello DELETE GET - http://localhost:5000/user_list // Lista użytkowników GET - http://localhost:5000/abcd // Wzorzec strony dopasowany GET - http://localhost:5000/ab123cd // Wzorzec strony dopasowany GET - http://localhost:5000/abxxcd // Wzorzec strony dopasowany GET - http://localhost:5000/abcdef // Cannot GET /abcdef Reakcja serwera: http://localhost:5000/ - Przykładowa aplikacja nasłuchuje na http://0.0.0.0:5000 Otrzymano żądanie GET dla strony głównej Otrzymano żądanie POST dla strony głównej Otrzymano żądanie DELETE dla strony /usun Otrzymano żądanie GET dla strony /user_list Otrzymano żądanie GET dla strony /ab*cd Otrzymano żądanie GET dla strony /ab*cd Otrzymano żądanie GET dla strony /ab*cd
MEAN Stack - Node.js, Express.js 50/61 Trasowanie - dostępne metody Express udostępnia metody do rootingu (trasowania) zgodne z metodami protokołu HTTP: get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, unsubscribe, patch, search, connect. Dla metod, których nazwy nie są poprawnymi nazwami JavaScript używamy notacji z nawiasami kwadratowymi: app['m-search']('/', function...
MEAN Stack - Node.js, Express.js 51/61 Express, statyczne pliki Express posiada wbudowaną warstwę pośrednią express.static, która pozwala na udostępnianie statycznych plików (obrazy, CSS, HTML, JavaScript,...) Wystarczy przekazać nazwę katalogu, z którego pliki będą dostępnę poprzez serwer: app.use(express.static( public )); var express = require('express'); var app = express(); app.use(express.static('public')); app.get('/', function (req, res) { res.send('hello World'); }) var server = app.listen(5000, function () { var host = server.address().address var port = server.address().port console.log("przykładowa aplikacja nasłuchuje na http://%s:%s", host, port) }) Wywołanie: http://localhost:5000/npmlogo.png wyświetli odpowiedni plik znajdujący się w katalogu public.
MEAN Stack - Node.js, Express.js 52/61 Formularze, metoda GET form get.js var express = require('express'); var app = express(); app.get('/get.html', function (req, res) { res.sendfile( dirname + "/" + "get.html" ); }) app.get('/form_get', function (req, res) { response = { imie:req.query.imie, nazwisko:req.query.nazwisko }; console.log(response); res.end(json.stringify(response)); }) app.listen(5000); get.html <html> <body> <form action="http://127.0.0.1:5000/form_get" method="get"> Imie: <input type="text" name="imie"> <br> Nazwisko: <input type="text" name="nazwisko"> <input type="submit" value="wyślij"> </form> </body> </html>
MEAN Stack - Node.js, Express.js 53/61 Formularze, metoda POST form post.js var express = require('express'); var app = express(); var bodyparser = require('body-parser'); var urlencodedparser = bodyparser.urlencoded({ extended: false }) // application/x-www-form-urlencoded app.use(express.static('public')); app.post('/form_post', urlencodedparser, function (req, res) { response = { imie:req.body.imie, nazwisko:req.body.nazwisko }; console.log(response); res.end(json.stringify(response)); }) app.listen(5000); post.html <html> <body> <form action="http://127.0.0.1:5000/form_post" method="post"> Imie: <input type="text" name="imie"> <br> Nazwisko: <input type="text" name="nazwisko"> <input type="submit" value="wyślij"> </form> </body> </html>
MEAN Stack - Node.js, Express.js 54/61 Formularze, przesyłanie plików I file upload.js var express = require('express'); var bodyparser = require('body-parser'); var multer = require('multer'); var app = express(); app.use(express.static('public')); app.use(bodyparser.urlencoded({ extended: false })); var upload = multer({ dest: 'uploads/' }).single('file'); app.post('/file_upload', function(req, res) { upload(req, res, function (err) { if (err) { // błąd przy wczytywaniu/przesyłaniu pliku return } // wszystko poszło dobrze console.log(req.file); // req.file zawiera opis przesyłanego pliku console.log(req.body); // req.body przechowuje pola tekstowe, jeśli takie były response = { message:'plik wczytany poprawnie', filename:req.file.filename, originalname:req.file.originalname, mimetype:req.file.mimetype, size:req.file.size }; res.end( JSON.stringify( response ) ); }) }) var server = app.listen(5000);
MEAN Stack - Node.js, Express.js 55/61 Formularze, przesyłanie plików II file.html <html> <head> </head> <body> Wybierz plik do wysłania: <br /> <form action="http://127.0.0.1:5000/file_upload" method="post" enctype="multipart/form-data"> <input type="file" name="file" size="50" /> <br> <input type="submit" value="wyślij plik" /> </form> </body> </html>
EAN Stack - Node.js, Express.js 56/61 Express, cookie-parser https://github.com/expressjs/cookie-parser $ npm install cookie-parser cookies.js var express = require('express') var cookieparser = require('cookie-parser') var app = express() app.use(cookieparser()) app.get('/', function(req, res) { console.log("cookies: ", req.cookies) }) app.listen(5000); Wynik: $ curl http://127.0.0.1:5000 --cookie "name=jan;pozd=hello" Cookies: { name: 'Jan', pozd: 'Hello' }
MEAN Stack - Node.js, Express.js 57/61 API, metoda GET server.js var express = require('express'); var app = express(); var fs = require("fs"); app.get('/listusers', function (req, res) { fs.readfile( dirname + "/" + "users.json", 'utf8', function (err, data) { console.log( data ); res.end( data ); }); }) app.listen(5000); Żądanie: http://localhost:5000/listusers { "user1" : { "name" : "johnw", "password" : "dogville321", "profession" : "film_director", "id": 1 }, "user2" : { "name" : "Halina", "password" : "MojeHaslo123", "profession" : "pisarka", "id": 2 }, "user3" : { "name" : "jnowak", "password" : "wiosna2016", "profession" : "malarz", "id": 3 } }
MEAN Stack - Node.js, Express.js 58/61 API, metoda GET, konkretny użytkownik server.js var express = require('express'); var app = express(); var fs = require("fs"); app.get('/:id', function (req, res) { fs.readfile( dirname + "/" + "users.json", 'utf8', function (err, data) { users = JSON.parse( data ); var user = users["user" + req.params.id] console.log( user ); res.end( JSON.stringify(user)); }); }) app.listen(5000); Żądanie: http://localhost:5000/1 { "name":"johnw", "password":"dogville321", "profession":"film_director", "id":1 }
MEAN Stack - Node.js, Express.js 59/61 API, metoda POST server.js... var user = { "user4" : { "name" : "kim2l", "password" : "a2vxzh45xr", "profession" : "programmer", "id": 4 } } app.get('/adduser', function (req, res) { fs.readfile( dirname + "/" + "users.json", 'utf8', function (err, data) { data = JSON.parse( data ); data["user4"] = user["user4"]; console.log( data ); res.end( JSON.stringify(data)); }); })... Żądanie: http://localhost:5000/adduser {... "user4" : { "name" : "kim2l", "password" : "a2vxzh45xr", "profession" : "programmer", "id": 4 } }
MEAN Stack - Node.js, Express.js 60/61 API, metoda DELETE server.js... var id = 2; app.get('/deleteuser', function (req, res) { fs.readfile( dirname + "/" + "users.json", 'utf8', function (err, data) { data = JSON.parse( data ); delete data["user" + id]; console.log( data ); res.end( JSON.stringify(data)); }); })... Żądanie: http://localhost:5000/deleteuser { "user1" : { "name" : "johnw", "password" : "dogville321", "profession" : "film_director", "id": 1 }, "user3" : { "name" : "jnowak", "password" : "wiosna2016", "profession" : "malarz", "id": 3 } }
MEAN Stack - Node.js, Express.js 61/61 Źródła https://nodejs.org/en/ https://en.wikipedia.org/wiki/node.js http://expressjs.com/ https://en.wikipedia.org/wiki/express.js http://www.tutorialspoint.com/nodejs/index.htm https://www.npmjs.com/ https://github.com/libuv/libuv https://en.wikipedia.org/wiki/callback_(computer_programming)