Cvičení – vytvoření základní webové aplikace

Dokončeno

Zatím máte Na virtuálním počítači s Ubuntu nainstalovaný MongoDB a Node.js. Teď vytvoříte základní webovou aplikaci, abyste se mohli podívat, jak to celé funguje. Na cestě uvidíte, jak se AngularJS a Express vejdou.

Naučíte se to na příkladech. Webová aplikace, kterou vytvoříte, implementuje základní databázi knih. Webová aplikace umožňuje vypsat informace o knihách, přidávat nové knihy a odstraňovat existující knihy.

Webová aplikace, kterou zde vidíte, ukazuje mnoho konceptů, které platí pro většinu webových aplikací zásobníku MEAN. Pokud tyto funkce potřebujete nebo se o ně zajímáte, můžete je prozkoumat a použít k vytvoření vlastních aplikací zásobníku MEAN.

Takto vypadá webová aplikace Books.

Snímek obrazovky webové stránky s formulářem a tlačítkem pro odeslání

Spolupráce jednotlivých komponent zásobníku MEAN

  • V databázi MongoDB jsou uložené informace o knihách.
  • Express.js směruje každý požadavek HTTP na příslušnou obslužnou rutinu.
  • AngularJS spojuje uživatelské rozhraní s obchodní logikou programu.
  • Node.js hostuje serverovou aplikaci.

Důležité

Pro studijní účely budete vytvářet základní webovou aplikaci. Na této aplikaci otestujete zásobník MEAN, abyste získali představu o jeho funkci. Aplikace není dostatečně zabezpečená nebo připravená k použití v produkčním prostředí.

A co komponenta Express?

Zatím jste na virtuální počítač nainstalovali MongoDB a Node.js. A co Express.js, E ve zkratce MEAN?

Express.js je architektura webového serveru vytvořená pro Node.js, která zjednodušuje proces vytváření webových aplikací.

Hlavním úkolem platformy Express je směrování požadavků. Směrování se týká způsobu, jakým aplikace reaguje na požadavek určitého koncového bodu. Koncový bod se skládá z cesty nebo identifikátoru URI a metody požadavku, jako je GET nebo POST. Například na požadavek GET, který se týká koncového bodu /book, můžete reagovat tak, že poskytnete seznam všech knih v databázi. Na požadavek POST na /book koncový bod můžete odpovědět tak, že do databáze přidáte položku na základě polí, která uživatel zadal do webového formuláře.

Ve webové aplikaci, kterou za chvíli sestavíte, použijete Express ke směrování požadavků HTTP a k vrácení webového obsahu uživateli. Express také umožňuje webovým aplikacím pracovat s HTTP soubory cookie a zpracovávat řetězce požadavků.

Express je balíčkem Node.js. K instalaci a správě balíčků Node.js slouží utilita npm, která je součástí Node.js. Později v této lekci vytvoříte soubor s názvem package.json Pro definování Expressu a dalších závislostí a pak spustíte npm install příkaz pro instalaci těchto závislostí.

A co komponenta AngularJS?

Stejně jako Express, AngularJS, A ve zkratce MEAN, ještě není nainstalovaný.

AngularJS usnadňuje psaní a testování webových aplikací, protože umožňuje lépe oddělit vzhled webové stránky – kód HTML – od chování webové stránky. Pokud znáte modelový model -view-controller (MVC) nebo koncept datové vazby, měli byste znát AngularJS.

AngularJS je front-endová javascriptová architektura, což znamená, že musí být k dispozici pouze v klientovi, který přistupuje k aplikaci. Jinými slovy AngularJS běží ve webovém prohlížeči uživatele, nikoli ve vašem webovém prohlížeči. AngularJS je JavaScript, který můžete použít k jednoduchému načtení dat z webového serveru, aby bylo možné je zobrazit na stránce.

Ve skutečnosti se AngularJS neinstaluje. Místo toho na stránku HTML přidáváte odkazy na javascriptový soubor na stránce HTML úplně stejně jako u jiných javascriptových knihoven. Existují různé způsoby, jak zahrnout AngularJS do svých webových stránek. Tady načtete AngularJS ze sítě pro doručování obsahu (CDN). CDN představuje způsob geografické distribuce obrázků, videa a dalšího obsahu, který zlepšuje rychlost stahování.

Tento kód zatím nepřidávejte, ale tady je příklad, který načte AngularJS z CDN. Tento kód obvykle přidáte do <head> oddílu stránky HTML.

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>

Poznámka:

Pozor na záměnu AngularJS s Angular. I když mají řadu věcí společných, AngularJS je předchůdcem rozhraní Angular. AngularJS se stále běžně používá k vytváření webových aplikací. AngularJS je založený na jazyku JavaScript. Angular je založený na programovacím jazyku TypeScript, který usnadňuje psaní javascriptových programů.

Návody sestavit aplikaci?

Tady použijete základní proces. Napíšete kód aplikace z Cloud Shellu a pak pomocí protokolu SCP (Secure Copy Protocol) zkopírujete soubory do virtuálního počítače. Pak spustíte Node.js aplikaci a zobrazí se výsledky v prohlížeči.

V praxi byste obvykle psali a testovat webovou aplikaci v místním prostředí, například z přenosného počítače nebo z virtuálního počítače, který spouštíte místně. Kód můžete uložit do systému správy verzí, jako je Git. Pak pomocí systému kontinuální integrace a průběžného doručování (CI/CD), jako je Azure DevOps, otestujte změny a nahrajte je do virtuálního počítače. Na konci tohoto modulu vás nasměrujeme na další zdroje informací.

Vytvoření webové aplikace Books

Tady vytvoříte veškerý kód, skript a soubory HTML, které tvoří vaši webovou aplikaci. Kvůli stručnosti zvýrazníme důležité části každého souboru, ale nezacházíme do úplných podrobností.

Pokud jste stále připojeni k virtuálnímu počítači přes SSH, spusťte příkaz exit, kterým ukončíte relaci SSH a vrátíte se do editoru Cloud Shell.

exit

Teď jste zpátky v relaci editoru Cloud Shell.

Vytvoření souborů

  1. Spuštěním těchto příkazů v Cloud Shellu vytvořte složky a soubory pro vaši webovou aplikaci:

    cd ~
    mkdir Books
    touch Books/server.js
    touch Books/package.json
    mkdir Books/app
    touch Books/app/model.js
    touch Books/app/routes.js
    mkdir Books/public
    touch Books/public/script.js
    touch Books/public/index.html
    

    Webová aplikace obsahuje následující složky a soubory:

    • Books je kořenový adresář projektu.
      • server.js definuje vstupní bod webové aplikace. Načte potřebné balíčky Node.js, určí port používaný k naslouchání a začne naslouchat příchozímu provozu protokolu HTTP.
      • package.json poskytuje informace o aplikaci, jako je její název, popis a balíčky Node.js, které aplikace potřebuje spustit.
    • Books/app – obsahuje kód, který běží na serveru.
      • model.js definuje připojení a schéma databáze. Můžete si ho představit jako datový model aplikace.
      • routes.js zpracovává směrování požadavků. Definuje třeba požadavky GET, které se týkají koncového bodu /book, poskytnutím seznamu všech knih v databázi.
    • Books/public – obsahuje soubory poskytované přímo prohlížeči klienta.
      • index.html obsahuje indexovou stránku. Obsahuje webový formulář, který uživateli umožňuje odesílat informace o knihách. Zobrazuje také všechny knihy v databázi a umožňuje z databáze odstraňovat záznamy.
      • script.js obsahuje javascriptový kód, který se spouští v prohlížeči uživatele. Umožňuje posílat serveru požadavky na výpis knih, přidávat knihy do databáze nebo je z ní odstraňovat.
  2. Když spustíte příkaz code, otevřete soubory v editoru Cloud Shell.

    code Books
    

Vytvoření datového modelu

  1. V editoru otevřete app/model.js a přidejte následující kód:

    var mongoose = require('mongoose');
    var dbHost = 'mongodb://localhost:27017/Books';
    mongoose.connect(dbHost, { useNewUrlParser: true } );
    mongoose.connection;
    mongoose.set('debug', true);
    var bookSchema = mongoose.Schema( {
        name: String,
        isbn: {type: String, index: true},
        author: String,
        pages: Number
    });
    var Book = mongoose.model('Book', bookSchema);
    module.exports = Book;
    

    Důležité

    Pokaždé, když v editoru vložíte do souboru kód nebo ho změníte, nezapomeňte ho uložit. Použijte nabídku „...“ nebo klávesovou zkratku (ve Windows a Linuxu Ctrl+S, v macOS Command+S).

    V tomto kódu se pro zjednodušení k přenosu dat do nebo z databáze MongoDB používá Mongoose. Mongoose je systém založený na schématu, který se používá k modelování dat. Kód definuje databázový dokument s názvem „Book“ se zadaným schématem. Schéma definuje čtyři pole používaná k popisu jedné knihy:

    • Název knihy nebo její nadpis
    • Jeho mezinárodní standardní číslo knihy (ISBN), které jednoznačně identifikuje knihu
    • Autor knihy
    • Počet stránek

    Dále vytvoříte obslužné rutiny HTTP, které mapuje požadavky GET, POST a DELETE na databázové operace.

Vytvoření tras Express.js, které zpracovávají požadavky HTTP

  1. V editoru otevřete app/routes.js a přidejte následující kód:

    var path = require('path');
    var Book = require('./model');
    var routes = function(app) {
        app.get('/book', function(req, res) {
            Book.find({}, function(err, result) {
                if ( err ) throw err;
                res.json(result);
            });
        });
        app.post('/book', function(req, res) {
            var book = new Book( {
                name:req.body.name,
                isbn:req.body.isbn,
                author:req.body.author,
                pages:req.body.pages
            });
            book.save(function(err, result) {
                if ( err ) throw err;
                res.json( {
                    message:"Successfully added book",
                    book:result
                });
            });
        });
        app.delete("/book/:isbn", function(req, res) {
            Book.findOneAndRemove(req.query, function(err, result) {
                if ( err ) throw err;
                res.json( {
                    message: "Successfully deleted the book",
                    book: result
                });
            });
        });
        app.get('*', function(req, res) {
            res.sendFile(path.join(__dirname + '/public', 'index.html'));
        });
    };
    module.exports = routes;
    

    Kód vytvoří pro aplikaci čtyři trasy. Tady je stručný popis každé trasy.

    Příkaz HTTP Koncový bod Popis
    GET /book Načte z databáze všechny knihy.
    POST /book Vytvoří objekt Book, který je založený na polích zadaných uživatelem ve webovém formuláři, a zapíše ho do databáze.
    DELETE /book/:isbn Odstraní z databáze knihu s odpovídajícím číslem ISBN.
    GET * Pokud nenajde vyhovující trasu, vrátí indexovou stránku.

    Express.js může obsluhovat odpovědi HTTP přímo v kódu pro zpracování tras nebo může obsluhovat statický obsah ze souborů. V tomto kódu si ukážeme obojí. První tři trasy vrací na požadavky z rozhraní API, které se týkají knih, data JSON. Čtvrtá trasa (výchozí) vrátí obsah souboru s indexem index.html.

Vytvoření klientské javascriptové aplikace

  1. V editoru otevřete soubor public/script.js a přidejte do něj tento kód:

    var app = angular.module('myApp', []);
    app.controller('myCtrl', function($scope, $http) {
        var getData = function() {
            return $http( {
                method: 'GET',
                url: '/book'
            }).then(function successCallback(response) {
                $scope.books = response.data;
            }, function errorCallback(response) {
                console.log('Error: ' + response);
            });
        };
        getData();
        $scope.del_book = function(book) {
            $http( {
                method: 'DELETE',
                url: '/book/:isbn',
                params: {'isbn': book.isbn}
            }).then(function successCallback(response) {
                console.log(response);
                return getData();
            }, function errorCallback(response) {
                console.log('Error: ' + response);
            });
        };
        $scope.add_book = function() {
            var body = '{ "name": "' + $scope.Name +
            '", "isbn": "' + $scope.Isbn +
            '", "author": "' + $scope.Author +
            '", "pages": "' + $scope.Pages + '" }';
            $http({
                method: 'POST',
                url: '/book',
                data: body
            }).then(function successCallback(response) {
                console.log(response);
                return getData();
            }, function errorCallback(response) {
                console.log('Error: ' + response);
            });
        };
    });
    

    Všimněte si, jak tento kód definuje modul pojmenovaný myApp a kontroler s názvem myCtrl. Nebudeme se tu podrobně zabývat funkcí modulu a kontrolerů, ale použijeme tyto názvy v dalším kroku, ve kterém svážete uživatelské rozhraní (kód HTML) s obchodní logikou aplikace.

    Předtím jste vytvořili čtyři trasy, které na serveru zpracovávají jednotlivé operace GET, POST a DELETE. Tento kód odpovídá stejným operacím, akorát na straně klienta (ve webovém prohlížeči uživatele).

    Například funkce getData pošle koncovému bodu /book požadavek GET. Vzpomeňte si, že server zpracovává tento požadavek načtením informací o všech knihách z databáze a vrácením těchto informací jako dat JSON v odpovědi. Všimněte si, jak se k proměnné přiřadí $scope.books data JSON v odpovědi. Dozvíte se, jak tento kód ovlivňuje to, co uživatel uvidí na webové stránce v dalším kroku.

    Tento kód při načtení stránky volá funkci getData. Prohlédněte si funkce del_book a add_book, abyste zjistili, jak fungují. Ke spárování výchozí obslužné rutiny serveru nepotřebujete kód na straně klienta, protože výchozí obslužná rutina vrátí indexovou stránku a ne data JSON.

Vytvoření uživatelského rozhraní

  1. V editoru otevřete soubor public/index.html a přidejte do něj tento kód:

    <!doctype html>
    <html ng-app="myApp" ng-controller="myCtrl">
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
        <script src="script.js"></script>
    </head>
    <body>
        <div>
        <table>
            <tr>
            <td>Name:</td>
            <td><input type="text" ng-model="Name"></td>
            </tr>
            <tr>
            <td>Isbn:</td>
            <td><input type="text" ng-model="Isbn"></td>
            </tr>
            <tr>
            <td>Author:</td>
            <td><input type="text" ng-model="Author"></td>
            </tr>
            <tr>
            <td>Pages:</td>
            <td><input type="number" ng-model="Pages"></td>
            </tr>
        </table>
        <button ng-click="add_book()">Add</button>
        </div>
        <hr>
        <div>
        <table>
            <tr>
            <th>Name</th>
            <th>Isbn</th>
            <th>Author</th>
            <th>Pages</th>
            </tr>
            <tr ng-repeat="book in books">
            <td><input type="button" value="Delete" data-ng-click="del_book(book)"></td>
            <td>{{book.name}}</td>
            <td>{{book.isbn}}</td>
            <td>{{book.author}}</td>
            <td>{{book.pages}}</td>
            </tr>
        </table>
        </div>
    </body>
    </html>
    

    Tento kód vytvoří základní html formulář se čtyřmi poli pro odeslání dat knihy a tabulky, která zobrazí všechny knihy uložené v databázi.

    I když je tento kód HTML standardní, ng- atributy HTML pro vás můžou být neznámé. Tyto atributy HTML spojují kód AngularJS s uživatelským rozhraním. Třeba když vyberete Přidat, volá kód AngularJS funkci add_book, která odešle data z formuláře na server.

    Tady můžete prozkoumat kód, abyste získali představu o tom, jak každý z ng- atributů souvisí s obchodní logikou aplikace.

Vytvoření serveru Express.js pro hostování aplikace

  1. V editoru otevřete soubor server.js a přidejte do něj tento kód:

    var express = require('express');
    var bodyParser = require('body-parser');
    var app = express();
    app.use(express.static(__dirname + '/public'));
    app.use(bodyParser.json());
    require('./app/routes')(app);
    app.set('port', 80);
    app.listen(app.get('port'), function() {
        console.log('Server up: http://localhost:' + app.get('port'));
    });
    

    Tento kód vytvoří samotnou webovou aplikaci. Obsluhuje statické soubory z public adresáře a používá trasy, které jste definovali dříve ke zpracování požadavků.

Definování informací o balíčku a jeho závislostí

Možná si vzpomínáte, že package.json poskytuje informace o vaší aplikaci, jako je její název a popis, a také o balíčcích Node.js, které aplikace potřebuje spustit.

  1. V editoru otevřete soubor package.json a přidejte do něj tento kód:

    {
      "name": "books",
      "description": "Sample web app that manages book information.",
      "license": "MIT",
      "repository": {
        "type": "git",
        "url": "https://github.com/MicrosoftDocs/mslearn-build-a-web-app-with-mean-on-a-linux-vm"
      },
      "main": "server.js",
      "dependencies": {
        "express": "~4.16",
        "mongoose": "~5.3",
        "body-parser": "~1.18"
      }
    }
    

Zobrazí se informace neboli metadata o vaší aplikaci, včetně jejího názvu, popisu a licence.

Pole repository určuje, kde je uložený kód. Později si kód můžete prohlédnout na GitHubu na uvedené adrese URL.

Pole main definuje vstupní bod aplikace. Poskytujeme ho tady pro úplnost. Vstupní bod je ale důležitý jenom v případě, že plánujete publikovat aplikaci jako balíček Node.js pro ostatní ke stažení a použití.

Pole dependencies je důležité. Definuje balíčky Node.js, které aplikace potřebuje. Za chvíli se k virtuálnímu počítači připojíte podruhé a spustíte npm install příkaz pro instalaci těchto balíčků.

U balíčků Node.js se většinou používá schéma sémantických verzí. Číslo verze má tři části: hlavní verzi, dílčí verzi a opravu. Tilda ~ zde říká utilitě npm, aby pod zadanou hlavní a dílčí verzi nainstalovala nejnovější verzi balíčku. Zde uvedené verze jsou nejnovější verze, se kterými byl tento modul testován. V praxi můžete postupně zvyšovat verzi, když aplikaci aktualizujete a testujete kvůli použití nejnovějších funkcí, které nabízí každý závislý balíček.

Kopírování souborů do virtuálního počítače

Než budete pokračovat, ujistěte se, že máte k dispozici IP adresu vašeho virtuálního počítače. Pokud ho nemáte, spusťte z Cloud Shellu tyto příkazy, které ho načtou:

ipaddress=$(az vm show \
  --name MeanStack \
  --resource-group "<rgn>[sandbox resource group name]</rgn>" \
  --show-details \
  --query [publicIps] \
  --output tsv)
echo $ipaddress
  1. Všechny soubory jsou upravené. Ujistěte se, že jste uložili změny jednotlivých souborů, a pak editor zavřete.

    Editor zavřete tak, že vyberete tři tečky v pravém horním rohu a pak vyberete Zavřít editor.

  2. Spuštěním následujícího scp příkazu zkopírujte obsah ~/Books adresáře v relaci Cloud Shellu do stejného názvu adresáře na virtuálním počítači:

    scp -r ~/Books azureuser@$ipaddress:~/Books
    

Instalace dalších balíčků Node

Řekněme, že během procesu vývoje jste identifikovali více balíčků Node, které chcete použít. Možná si vzpomínáte, že app/model.js začíná tímto řádkem:

var mongoose = require('mongoose');

Řekli jsme si, že aplikace používá k přenosu dat do nebo z databáze MongoDB webový server Mongoose.

Aplikace také vyžaduje Express.js a balíčky body-parser. Body-parser je modul plug-in, který umožňuje Expressu pracovat s daty z webového formuláře odeslaného klientem.

Pojďme se připojit k virtuálnímu počítači a nainstalovat balíčky uvedené v souboru package.json.

  1. Před připojením k virtuálnímu počítači si nezapomeňte připravit ID adresu virtuálního počítače. Pokud ho nemáte, načtěte ho spuštěním příkazů Cloud Shellu v předchozí části.

  2. Vytvořte připojení SSH k virtuálnímu počítači, jak jste to udělali dříve:

    ssh azureuser@$ipaddress
    
  3. Přejděte do Books adresáře v domovském adresáři:

    cd ~/Books
    
  4. Spusťte npm install instalaci závislých balíčků:

    sudo apt install npm -y && npm install
    

Nechte připojení SSH otevřené pro další část.

Testování aplikace

Teď můžete svou webovou aplikaci Node.js otestovat.

  1. ~/Books Z adresáře spusťte tento příkaz a spusťte webovou aplikaci:

    sudo nodejs server.js
    

    Tímto příkazem spustíte aplikaci, která naslouchá příchozím požadavkům HTTP na portu 80.

  2. Na oddělené kartě prohlížeče přejděte na veřejnou IP adresu virtuálního počítače.

    Zobrazí se indexová stránka, která obsahuje webový formulář.

    Snímek obrazovky webové stránky knihy s formulářem a tlačítkem pro odeslání

    Zkuste do databáze přidat několik knížek. Pokaždé, když přidáte knížku, se na stránce aktualizuje seznam všech knih.

    Snímek obrazovky webové stránky knihy s načtenými ukázkovými daty

    Pokud chcete knihu z databáze odstranit, můžete také vybrat Odstranit.