Alıştırma - Temel bir web uygulaması oluşturma

Tamamlandı

Bu noktaya kadar Ubuntu VM'nize MongoDB ve Node.js uygulamalarını yüklediniz. Artık basit bir web uygulaması oluşturarak bu işlevleri uygulamalı olarak görebilirsiniz. Bu sırada AngularJS ve Express uygulamalarının da sürece nasıl dahil olduğunu göreceksiniz.

En iyi öğrenme yollarından biri örnekler üzerinden ilerlemektir. Oluşturacağınız web uygulaması, basit bir kitap veritabanına sahip olacak. Web uygulaması kitaplar hakkındaki bilgileri listelemenize, yeni kitaplar eklemenize ve var olan kitapları silmenize olanak tanır.

Burada gördüğünüz web uygulamasında, çoğu MEAN yığını web uygulaması için geçerli olan kavramlar gösterilmektedir. Gereksinimlerinize ve ilgilendiğiniz alanlara göre kendi MEAN yığını uygulamalarınızı oluşturmak için ihtiyacınız olan özellikleri keşfedebilirsiniz.

Books web uygulaması aşağıdaki bileşenlere sahip olacaktır.

Screenshot of a web page with a form and submission button.

Burada MEAN yığınındaki her bir bileşen aşağıdaki görevleri üstlenir.

  • MongoDB, kitaplar hakkındaki bilgileri depolar.
  • Express.js her HTTP isteğini uygun işleyiciye yönlendirir.
  • AngularJS, kullanıcı arabirimiyle programın iş mantığı arasında bağlantı kurar.
  • Node.js, sunucu tarafındaki uygulamayı barındırır.

Önemli

Bu öğreticide basit bir web uygulaması oluşturuyorsunuz. Bu uygulamanın amacı, MEAN yığınınızı test etmek ve nasıl çalıştığı konusunda sizi bilgilendirmektir. Uygulama yeterince güvenli değildir veya üretim kullanımına hazır değildir.

Peki ya Express?

Bu noktaya kadar VM'nize MongoDB ve Node.js yüklediniz. Mean kısaltmasının E harfi olan Express.js ne olacak?

Express.js, node.js için oluşturulan ve web uygulamaları oluşturma işlemini basitleştiren bir web sunucusu çerçevesidir.

Express'in temel amacı istek yönlendirme sürecini yönetmektir. Yönlendirme, uygulamanın belirli bir uç noktaya gönderilen isteklere nasıl yanıt verdiğini belirtir. Uç nokta bir yol veya URI'nin yanı sıra GET veya POST gibi bir istek yönteminden oluşur. Örneğin /book uç noktasına yapılan bir GET isteğine veritabanındaki tüm kitapları listeleyerek yanıt verebilirsiniz. Aynı uç noktaya yapılan bir POST isteğine ise kullanıcının web formuna girdiği alanlara göre veritabanına bir giriş ekleyerek yanıt verebilirsiniz.

Oluşturacağınız web uygulamasında HTTP isteklerini yönlendirmek ve kullanıcınıza web içeriği döndürmek için Express'i kullanacaksınız. Express aynı zamanda web uygulamalarınızın HTTP tanımlama bilgileri ile çalışmasına ve sorgu dizelerini işlemesine de yardımcı olabilir.

Express bir Node.js paketidir. Node.js paketlerini yüklemek ve yönetmek için Node.js ile birlikte gelen npm yardımcı programını kullanırsınız. Bu ünitenin ilerleyen bölümlerinde Express ve diğer bağımlılıkları tanımlamak için adlı package.json bir dosya oluşturacak ve ardından komutunu çalıştırarak npm install bu bağımlılıkları yükleyeceksiniz.

Peki ya AngularJS?

Express gibi MEAN kısaltmasının A harfine karşılık gelen AngularJS'yi de henüz yüklemediniz.

AngularJS, web sayfanızın görünümünü (HTML kodunuz) web sayfanızın davranışından daha iyi ayırmanıza olanak sağladığından web uygulamalarının yazılmasını ve test edilmesini kolaylaştırır. Model-görünüm-denetleyici (MVC) deseni veya veri bağlama kavramı konusunda bilgi sahibiyseniz AngularJS size tanıdık gelecektir.

AngularJS bir ön uç JavaScript çerçevesidir ve bu nedenle uygulamaya erişen istemcide bulunması gerekir. Başka bir deyişle AngularJS, web sunucunuzda değil kullanıcınızın web tarayıcısında çalışır. AngularJS bir JavaScript bileşeni olduğundan web sunucunuzdaki verileri kolayca getirerek sayfada gösterebilirsiniz.

AngularJS’yi gerçekten yüklemezsiniz. Bunun yerine diğer JavaScript kitaplıklarında olduğu gibi HTML sayfanızda JavaScript dosyasına başvuru eklersiniz. AngularJS'yi web sayfalarınıza dahil etmek için kullanabileceğiniz birçok yöntem vardır. Burada, angularJS'yi bir içerik teslim ağından veya CDN'den yükleyeceksiniz. CDN, indirme hızlarını iyileştirme amacıyla görüntüleri, videoları ve diğer içerikleri coğrafi olarak dağıtma yöntemidir.

Burada CDN'den AngularJS yükleme örneği verilmiştir. Bu kodu henüz uygulamanıza eklemeyin. Bu kodu <head> genellikle HTML sayfanızın bölümüne eklersiniz.

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

Dekont

AngularJS ile Angular'ı birbirine karıştırmayın. İki bileşenin kavramlarının çoğu benzer olsa da AngularJS, Angular'ın öncülüdür. AngularJS hala web uygulaması oluşturmak için yaygın olarak kullanılır. AngularJS, JavaScript'i temel alırken Angular, JavaScript programlarını yazmayı kolaylaştıran bir programlama dili olan TypeScript'i temel alır.

Uygulamayı nasıl derleyeceğim?

Burada basit bir süreç izleyeceksiniz. Cloud Shell'den uygulama kodunu yazacak ve güvenli kopyalama protokolünü (SCP) kullanarak dosyaları VM'nize kopyalayacaksınız. Ardından Node.js uygulamasını başlatacak ve sonuçları tarayıcınızda göreceksiniz.

Uygulamada genellikle web uygulamanızı dizüstü bilgisayarınızdan veya yerel olarak çalıştırdığınız bir sanal makine gibi daha yerel bir ortamda yazar ve test edebilirsiniz. Ardından kodunuzu Git gibi bir sürüm denetim sisteminde depolayabilir ve değişikliklerinizi test etmek ve vm'nize yüklemek için Azure DevOps gibi sürekli tümleştirme ve sürekli teslim veya CI/CD sistemi kullanabilirsiniz. Bu kaynaklarla ilgili daha fazla bilgiye ulaşabileceğiniz bağlantılar bu modülün sonunda verilmiştir.

Books web uygulamasını oluşturma

Burada web uygulamanızı oluşturan tüm kod, betik ve HTML dosyalarını oluşturacaksınız. Örneği uzatmama amacıyla her dosyanın önemli bölümlerini vurgulayacağız ve ayrıntıya girmeyeceğiz.

VM'nize SSH üzerinden bağlıysanız exit komutunu çalıştırarak SSH oturumundan çıkın ve Cloud Shell'e dönün.

exit

Cloud Shell oturumunuza dönmüş oldunuz.

Dosyaları oluşturma

  1. Cloud Shell'den şu komutları çalıştırarak web uygulamanız için klasörleri ve dosyaları oluşturun:

    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
    

    Şu bileşenler dahil edilmiştir:

    • Books projenin kök dizinidir.
      • server.js, web uygulamasının giriş noktasını tanımlar. Gerekli Node.js paketlerini yükler, dinleme yapılacak bağlantı noktasını belirtir ve gelen HTTP trafiğini dinlemeye başlar.
      • package.json adı, açıklaması ve çalışmak için ihtiyaç duyduğu Node.js paketleri dahil olmak üzere uygulamanızla ilgili bilgileri sağlar.
    • Books/app sunucuda çalışan kodu içerir.
      • model.js, veritabanı bağlantısını ve şemasını tanımlar. Bunu uygulamanızın veri modeli gibi düşünebilirsiniz.
      • routes.js, istek yönlendirme sürecini yönetir. Örneğin /book uç noktasına yapılan GET isteklerini, veritabanındaki tüm kitapları listeleyerek tanımlayabilir.
    • Books/public doğrudan istemcinin tarayıcısına sunulan dosyaları içerir.
      • index.html, dizin sayfasını içerir. Aynı zamanda kullanıcının kitaplarla ilgili bilgiler göndermesini sağlayan bir web formu da içerir. Ayrıca veritabanındaki tüm kitapları görüntüler ve veritabanındaki girişleri silmenizi sağlar.
      • script.js, kullanıcınızın tarayıcısında çalışan JavaScript kodunu içerir. Sunucuya kitapları listeleme, veritabanına kitap ekleme ve veritabanındaki kitapları silme istekleri gönderebilir.
  2. Dosyalarınızı Cloud Shell düzenleyicisinden açmak için code komutunu çalıştırın.

    code Books
    

Veri modelini oluşturma

  1. Düzenleyiciden aşağıdakileri açın app/model.js ve ekleyin:

    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;
    

    Önemli

    Düzenleyicide dosyaya her kod yapıştırdığınızda veya bir kodu değiştirdiğinizde "..." menüsünü veya kısayolu (Windows ve Linux’ta Ctrl+S, macOS’ta Command+S) kullanarak dosyayı kaydetmeyi unutmayın.

    MongoDB'de içeri ve dışarı veri aktarım sürecini kolaylaştırmak için bu kodda Mongoose kullanılmıştır. Mongoose, verileri modellemeye yönelik şema tabanlı bir sistemdir. Kod, verilen şemayla "Book" adlı bir veritabanı belgesi tanımlar. Şema, tek bir kitap tanımlayan dört alan tanımlar:

    • Kitabın adı veya başlığı
    • Kitabı benzersiz bir şekilde tanımlayan Uluslararası Standart Kitap Numarası (veya ISBN)
    • Yazarı
    • Sayfa sayısı

    Bir sonraki adımda GET, POST ve DELETE isteklerini veritabanı işlemleriyle eşleyen HTTP işleyicilerini oluşturacaksınız.

HTTP isteklerini işleyen Express.js yollarını oluşturma

  1. Düzenleyiciden aşağıdaki kodu açın app/routes.js ve ekleyin:

    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;
    

    Bu kod uygulama için dört yol oluşturur. Aşağıda her biri için kısa genel bakış bilgileri verilmiştir.

    HTTP fiili Uç nokta Açıklama
    GET /book Veritabanındaki tüm kitapları alır.
    POST /book Kullanıcının web formunda sağladığı alanları temel alan bir Book nesnesi oluşturur ve bu nesneyi veritabanına yazar.
    DELETE /book/:isbn ISBN değeriyle tanımlanan kitabı veritabanından siler.
    GET * Başka bir yol ile eşleşmediğinde dizin sayfasını döndürür.

    Express.js, HTTP yanıtlarını doğrudan yol işleme kodunda veya dosyalardan statik içerik sağlayabilir. Bu kodda iki durum da gösterilmiştir. İlk üç yol, kitap API'si istekleri için JSON verilerini döndürür. Dördüncü yol (varsayılan durum) index.html dizin dosyasının içeriğini döndürür.

İstemci tarafı JavaScript uygulamasını oluşturma

  1. public/script.js dosyasını düzenleyicide açın ve şu kodu ekleyin:

    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);
            });
        };
    });
    

    Kodun "myApp" adlı bir modül ve "myCtrl" adlı bir denetleyici tanımladığını göreceksiniz. Burada modül ve denetleyicilerin işlevlerini ayrıntılı bir şekilde incelemeyeceğiz ancak bu adları bir sonraki adımda kullanıcı arabirimini (HTML kodu) uygulamanın iş mantığına bağlamak için kullanacağız.

    Önceki bölümlerde sunucudaki GET, POST ve DELETE işlemlerini işleyen dört yol oluşturdunuz. Bu kod da bu işlemlere benzer ancak bu durumda işlemler istemci tarafında (kullanıcının web tarayıcısı) gerçekleştirilir.

    Örneğin getData işlevi /book uç noktasına bir GET isteği gönderir. Bildiğiniz gibi sunucu bu isteği veritabanındaki tüm kitaplarla ilgili bilgileri alıp JSON verisi olarak döndürerek işliyordu. Sonuçta elde edilen JSON verilerinin $scope.books değişkenine atandığına dikkat edin. Bir sonraki adımda bunun kullanıcının web sayfasında gördüklerini nasıl etkilediğini öğreneceksiniz.

    Bu kod, sayfa yüklendiğinde getData işlevini çağırır. del_book ve add_book işlevlerini inceleyerek nasıl çalıştıkları hakkında bilgi sahibi olabilirsiniz. Varsayılan işleyici JSON verilerini değil dizin sayfasını döndürdüğünden, sunucunun varsayılan işleyicisi ile eşleşmesi için istemci tarafı koduna ihtiyacınız yoktur.

Kullanıcı arabirimini oluşturma

  1. public/index.html dosyasını düzenleyicide açın ve şu kodu ekleyin:

    <!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>
    

    Bu kod, kitap verilerini göndermek için dört alan ve veritabanında depolanan tüm kitapları görüntüleyen bir tablo içeren temel bir HTML formu oluşturur.

    Bu standart HTML kodu olsa da ng- HTML öznitelikleri size yabancı gelmiş olabilir. Bu HTML öznitelikleri, AngularJS kodunu kullanıcı arabirimine bağlar. Örneğin Add (Ekle) düğmesini seçtiğinizde AngularJS form verilerini sunucuya gönderen add_book işlevini çağırır.

    Özniteliklerin her birinin ng- uygulamanın iş mantığıyla nasıl ilişkili olduğunu öğrenmek için buradaki kodu inceleyebilirsiniz.

Uygulamayı barındırmak için Express.js sunucusunu oluşturma

  1. server.js dosyasını düzenleyicide açın ve şu kodu ekleyin:

    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'));
    });
    

    Bu kod web uygulamasının kendisini oluşturur. Dizinden public statik dosyalara hizmet eder ve istekleri işlemek için daha önce tanımladığınız yolları kullanır.

Paket bilgilerini ve bağımlılıkları tanımlama

Hatırlayacağınız üzere package.json adı, açıklaması ve çalışmak için ihtiyaç duyduğu Node.js paketleri dahil olmak üzere uygulamanızla ilgili bilgileri sağlar.

  1. package.json dosyasını düzenleyicide açın ve şu kodu ekleyin:

    {
      "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"
      }
    }
    

Adı, açıklaması ve lisansı dahil olmak üzere uygulamanızla ilgili bilgileri veya meta verileri görürsünüz.

repository alanı kodun barındırıldığı yeri belirtir. Dilerseniz daha sonra burada gösterilen URL'yi kullanarak GitHub'daki kodu gözden geçirebilirsiniz.

main alanı uygulamanın giriş noktasını tanımlar. Tamlık için burada sağlanır, ancak uygulamanızı başkalarının indirip kullanması için Node.js paketi olarak yayımlamayı planlamadığınız için bu önemli değildir.

dependencies alanı önemlidir. Uygulamanızın ihtiyaç duyduğu Node.js paketlerini tanımlar. Birkaç adım sonra VM'nize ikinci kez bağlanıp npm install komutunu çalıştırarak bu paketleri yükleyeceksiniz.

Node paketleri genellikle Anlamsal Sürüm Oluşturma şemasını kullanır. Sürüm numarası üç bileşenden oluşur: ana sürüm, alt sürüm ve düzeltme eki. Buradaki tilde ~ gösterimi, npm'ye belirtilen ana ve alt sürümlerin altındaki en son düzeltme eki sürümünü yüklemesini söyler. Burada gördüğünüz sürümler, bu modülün test edildiği en son sürümlerdir. Gerçek hayatta uygulamanızı güncelleştirip test ederken sürümü artırabilir ve paketlerin sunduğu en güncel özelliklerden faydalanabilirsiniz.

Dosyaları VM'nize kopyalama

Devam etmeden önce VM'nizin IP adresinin kullanışlı olduğundan emin olun. Bu komutlara sahip değilseniz Cloud Shell'den şu komutları çalıştırarak alın:

ipaddress=$(az vm show \
  --name MeanStack \
  --resource-group "<rgn>[sandbox resource group name]</rgn>" \
  --show-details \
  --query [publicIps] \
  --output tsv)
echo $ipaddress
  1. Dosyaları düzenlemeyi tamamladınız. Değişiklikleri her dosyaya kaydettiğinizden emin olun ve düzenleyiciyi kapatın.

    Düzenleyiciyi kapatmak için sağ üst köşedeki üç noktayı ve ardından Düzenleyiciyi Kapat'ı seçin.

  2. Cloud Shell oturumunuzda dizinin içeriğini ~/Books VM'nizdeki aynı dizin adına kopyalamak için aşağıdaki scp komutu çalıştırın:

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

Ek Node paketlerini yükleme

Geliştirme sürecinde kullanmak istediğiniz ek Node paketleri olduğunu fark ettiğinizi düşünelim. Örneğin app/model.js paketinin bu satırla başladığını hatırlayın.

var mongoose = require('mongoose');

Uygulamanın MongoDB veritabanınızla veri alışverişi gerçekleştirmeyi kolaylaştırmak için Mongoose kullandığını hatırlayın.

Uygulama ayrıca Express.js ve body-ayrıştırıcı paketleri gerektirir. Gövde ayrıştırıcı, Express'in istemci tarafından gönderilen web formundaki verilerle çalışmasını sağlayan bir eklentidir.

Şimdi VM'nize bağlanıp package.json ile belirttiğiniz paketleri yükleyin.

  1. VM'nize bağlanmadan önce IP adresinin elinizin altında olduğundan emin olun. Sahip değilseniz, önceki bölümdeki Cloud Shell komutlarını çalıştırarak alın.

  2. Daha önce yaptığınız gibi VM'nize bir SSH bağlantısı oluşturun:

    ssh azureuser@$ipaddress
    
  3. Giriş dizininin Books altındaki dizine gitme:

    cd ~/Books
    
  4. Bağımlı paketleri yüklemek için komutunu çalıştırın npm install :

    sudo apt install npm -y && npm install
    

Sonraki bölüm için SSH bağlantınızı açık tutun.

Uygulamayı test etme

Artık Node.js web uygulamanızı yüklemeye hazırsınız!

  1. ~/Books Web uygulamasını başlatmak için dizininden şu komutu çalıştırın:

    sudo nodejs server.js
    

    Bu komut, gelen HTTP istekleri için 80 numaralı bağlantı noktasını dinleyerek uygulamayı başlatır.

  2. Ayrı bir tarayıcı sekmesinden VM'nizin genel IP adresine gidin.

    Web formunun bulunduğu dizin sayfasını görürsünüz.

    Screenshot of the book web page with a form and submission button.

    Veritabanına birkaç kitap eklemeyi deneyin. Her kitap eklediğinizde sayfadaki kitap listesi güncelleştirilir.

    Screenshot of the book web page with sample data populated.

    Ayrıca Sil düğmesini seçerek veritabanındaki kitapları silebilirsiniz.