Compartir a través de


Работа с хранилищем данных в облачном приложении Node.js на базе Express

В данном руководстве мы расширим возможности приложения, созданного в руководстве «Веб-приложение Node.js на базе модуля Express». Для этого мы добавим в него клиентские библиотеки Windows Azure для Node.js, обеспечивающие работу со службами хранения. Наше веб-приложение будет реализовывать список задач и развертываться на Windows Azure. Пользователь сможет получать и создавать задачи, а также помечать их как завершенные.

Физически задачи будут размещены в хранилище Windows Azure. Хранилище Windows Azure служит для отказоустойчивого и надежного хранения неструктурированных данных. Оно включает в себя несколько структур данных для хранения и доступа к информации, а службы хранения доступны с помощью API в Windows Azure SDK для Node.js или через API REST. Дополнительную информацию см. в разделе «Хранение и доступ к данным в Windows Azure».

Предполагается, что вы уже ознакомились с руководствами «Веб-приложение на базе Node.js» и «Node.js с модулем Express».

О чем пойдет речь в данном руководстве:

  • Как работать с процессором шаблонов Jade.
  • Как работать со службами хранилища Windows Azure.

Снимок экрана готового приложения приведен ниже.

clip_image002

Настройка учетных данных в файле Web.Config

Для доступа в хранилище Windows Azure необходимо передавать учетные данные. Их можно указать в настройках приложения (файл web.config). Эти настройки передаются в Node в виде переменных среды и затем считываются средствами Windows Azure SDK.

Примечание. Учетные данные используются только тогда, когда приложение развернуто в Windows Azure. Если запущен эмулятор, приложение будет использовать его.

Чтобы получить учетные данные для входа в хранилище и добавить их в файл web.config, выполните следующие действия:

Если эмулятор еще не запущен, откройте Windows Azure PowerShell в меню Start, выбрав All Programs, Windows Azure, щелкните правой кнопкой мыши Windows Azure PowerShell и выберите Run As Administrator.

Перейдите в каталог с приложением. Например, это может быть C:\node\tasklist\WebRole1.

В окне Windows Azure Powershell введите следующий командлет для получения учетных данных:

PS C:\node\tasklist\WebRole1> Get-AzureStorageAccounts

В результате будет возвращен список учетных записей хранилища и ключи, связанные с размещенной службой.

Примечание. Windows Azure SDK создает учетную запись хранилища при развертывании службы, поэтому учетная запись осталась после развертывания приложения (это было сделано ранее).

Откройте файл web.cloud.config с настройками среды, используемыми при развертывании приложения в Windows Azure:

PS C:\node\tasklist\WebRole1> notepad web.cloud.config

Вставьте приведенный ниже блок кода в элемент configuration, заменив {STORAGE ACCOUNT} и {STORAGE ACCESS KEY} на имя учетной записи и основной ключ хранения, которые вы будете использовать для развертывания:

<appSettings>
    <add key="AZURE_STORAGE_ACCOUNT" value="{STORAGE ACCOUNT}"/>
    <add key="AZURE_STORAGE_ACCESS_KEY" value="{STORAGE ACCESS KEY}"/>
</appSettings>
 

clip_image004

Сохраните файл и закройте Блокнот.

Установка модулей

Для работы со службами хранилища Windows Azure необходимо установить модуль Azure для Node, а также модуль node-uuid, который будет использоваться для создания идентификаторов UUID. Чтобы установить данные модули, введите следующую команду:

PS C:\node\tasklist\WebRole1> npm install node-uuid azure

В результате ее выполнения модули будут сохранены в папку node_modules. Чтобы подключить модули к приложению, выполните следующие действия:

Откройте файл server.js:

PS C:\node\tasklist\WebRole1> notepad server.js

2. Добавьте приведенный ниже код после строки, содержащей вызов функции express.createServer(), чтобы подключить модули node-uuid, home и azure. Модуль home пока отсутствует, но мы скоро его создадим.

clip_image006

var uuid = require('node-uuid');
var Home = require('./home');
var azure = require('azure');

Добавьте код, который будет передавать клиенту таблицы хранилища в учетной записи хранилища, а также ключ доступа.

Примечание. SDK автоматически использует запущенный эмулятор, даже если в файле web.config указаны учетные данные хранилища.

var client = azure.createTableService();

Затем создайте таблицу в вызванных задачах хранилища Windows Azure. Приведенный ниже код создает таблицу, если она отсутствует, и заполняет ее стандартными значениями.

//table creation
client.createTableIfNotExists('tasks', function(error){
    if(error){
        throw error;
    }

var item = {
    name: 'Add readonly task list',
    category: 'Site work',
    date: '12/01/2011',
    RowKey: uuid(),
    PartitionKey: 'partition1',
    completed: false
};

client.insertEntity('tasks', item, function(){});

});

Замените существующий код в разделе route на приведенный ниже код, который создает экземпляр контроллера home и маршрутизирует в него все запросы в каталог / или /home.

clip_image008

var home = new Home(client);
app.get('/', home.showItems.bind(home));
app.get('/home', home.showItems.bind(home));

Обратите внимание, что вместо контекстной обработки запроса команда делегируется объекту Home. Вызов команды bind гарантирует, что все эти ссылки будут правильно разрешены на локальном уровне (в контроллере home).

Создание контроллера Home

Теперь нужно создать контроллер home, который будет обрабатывать все запросы, поступающие на сайт со списком задач. Выполните следующие действия, чтобы создать контроллер:

Создайте файл home.js в Блокноте. В этом файле будет содержаться код контроллера, реализующий логику работы списка задач.

PS C:\node\tasklist\WebRole1> notepad home.js

Замените содержимое файла на приведенный ниже код и сохраните изменения. Код написан на основе шаблона модуля javascript с использованием функции Home. Прототип Home включает в себя обработчики реальных запросов.

var azure=require('azure');
module.exports = Home;

function Home (client) {
    this.client = client;
};

Home.prototype = {
    showItems: function (req, res) {
        var self = this;
        this.getItems(false, function (resp, tasklist) {
            if (!tasklist) {
                tasklist = [];
            }          
            self.showResults(res, tasklist);
        });
    },

getItems: function (allItems, callback) {
    var query = azure.TableQuery
        .select()
        .from('tasks');

    if (!allItems) {
        query = query.where('completed eq ?', 'false');
    }
    this.client.queryEntities(query, callback);
  },

  showResults: function (res, tasklist) {
    res.render('home', {
        title: 'Todo list',
        layout: false,
        tasklist: tasklist });
  },

};

Теперь в контроллере home есть три функции:

  • showItems обрабатывает запросы.
  • getItems получает задачи из таблицы задач посредством клиента таблицы. Обратите внимание, что к запросу можно применять дополнительные фильтры. Например, рассмотренный выше запрос отфильтровывает закрытые задачи.
  • showResults вызывает функцию прорисовки модуля Express, чтобы отобразить страницу в представлении home, которое мы создадим в следующем разделе.

Изменение представления Home

Процессор шаблонов Jade использует упрощенный по сравнению с HTML язык разметки и по умолчанию используется при работе с модулем Express. Чтобы создать представление, отображающее задачи из списка, выполните следующие действия:

В окне Windows PowerShell измените файл home.jade следующей командой:

PS C:\node\tasklist\WebRole1\views> notepad home.jade

Замените содержимое файла home.jade на приведенный ниже код и сохраните изменения. С помощью данной формы можно считывать и обновлять задачи из списка. (Обратите внимание, что сейчас контроллер home поддерживает только чтение. Мы изменим его чуть позже.) Форма содержит подробные сведения о каждом элементе списка задач.

html
head
    title Index
body
    h1 My ToDo List

form
    table(border="1")
        tr
            td Name
            td Category
            td Date
            td Complete

            each item in tasklist
                tr
                    td #{item.name}
                    td #{item.category}
                    td #{item.date}
                    td
                        input(type="checkbox", name="completed", value="#{item.RowKey}")

Запуск приложения в эмуляторе вычислений

В окне Windows PowerShell введите следующий командлет, чтобы запустить службу в эмуляторе вычислений и отобразить веб-страницу, запрашивающую эту службу.

PS C:\node\tasklist\WebRole1> Start-AzureEmulator -launch

В браузере откроется страница, на которой будет показана задача, полученная из хранилища Windows Azure:

clip_image010

Добавление функциональности для создания задач

В этом разделе показано, как реализовать создание задач в приложении.

Добавление маршрута в Server.js

Добавьте в файл server.js приведенную ниже строку сразу за последней записью маршрута в /home, а затем сохраните изменения.

clip_image012

app.post('/home/newitem', home.newItem.bind(home));

Теперь раздел routes будет выглядеть примерно так:

// Routes

    var home = new Home(client);
    app.get('/', home.showItems.bind(home));
    app.get('/home', home.showItems.bind(home));
    app.post('/home/newitem', home.newItem.bind(home));

Добавление модуля Node-UUID

Чтобы создать уникальный идентификатор с помощью модуля node-uuid, добавьте приведенную ниже строку в начало файла home.js после первой строки экспорта модуля.

clip_image014

var uuid = require('node-uuid');

Добавление функциональности для создания задач в контроллере Home

Чтобы реализовать возможность создания задач, добавьте функцию newItem. Вставьте приведенный ниже код в файл home.js сразу за последней функцией и сохраните изменения.

clip_image016

newItem: function (req, res) {
        var self = this;
        var createItem = function (resp, tasklist) {
            if (!tasklist) {
                tasklist = [];
            }

            var count = tasklist.length;

            var item = req.body.item;
            item.RowKey = uuid();
            item.PartitionKey = 'partition1';
            item.completed = false;

            self.client.insertEntity('tasks', item, function (error) {
                if(error){  
                    throw error;
                }
                self.showItems(req, res);
            });
        };

        this.getItems(true, createItem);
    },

Функция newItem выполняет следующие действия:

  • Извлекает размещенный элемент из раздела body.
  • Присваивает новому элементу значения RowKey и PartitionKey. Они нужны для вставки элемента в таблицу Windows Azure. Идентификатор UUID создается для значения RowKey.
  • Вставляет элемент в таблицу задач посредством вызова функции insertEntity.
  • Отображает страницу путем вызова функции getItems.

Добавление формы создания задачи в представлении Home

Теперь можно обновить представление, добавив в него форму для создания задач. Вставьте приведенный ниже код в конец файла home.jade и сохраните изменения.

Примечание. В языке разметки Jade пробелы являются значащими, поэтому не удаляйте их.

hr
    form(action="/home/newitem", method="post")
        table(border="1")    
            tr
                td Item Name:
                td
                    input(name="item[name]", type="textbox")
            tr
                td Item Category:
                td
                    input(name="item[category]", type="textbox")
            tr
                td Item Date:
                td
                    input(name="item[date]", type="textbox")
        input(type="submit", value="Add item")

Запуск приложения в эмуляторе

Поскольку эмулятор Windows Azure запущен, то можно просмотреть обновленное приложение.

PS C:\node\tasklist\WebRole1> start https://localhost:81/home

В браузере отобразится следующая страница:

clip_image018

Заполните поля следующим образом: Item Name: «Создание задач», Item Category: «Сайт работает?» и Item Date: «12.02.2011». Затем нажмите Add item.

Элемент будет добавлен в таблицу задач хранилища Windows Azure и появится на экране, как показано на снимке экрана ниже.

clip_image020

Повторная публикация приложения в Windows Azure

Теперь, когда приложение полностью готово, осталось опубликовать его в Windows Azure, обновив старое развертывание в размещенной службе.

В окне Windows PowerShell вызовите следующий командлет, чтобы повторно развернуть размещенную службу на Windows Azure. При этом уже существующие настройки хранения и местоположения не изменятся.

PS C:\node\tasklist\WebRole1> Publish-AzureServiceProject -name myuniquename -location datacentername -launch

После завершения развертывания на экране отобразится примерно следующее:

clip_image022

Поскольку мы, как и в предыдущих примерах, использовали ключ -launch, после окончания развертывания автоматически запустится браузер и отобразит приложение в Windows Azure.

clip_image024

Остановка и удаление приложения

В некоторых случаях может понадобиться отключить развернутое приложение, чтобы сэкономить средства или освободить место под другие приложения.

Оплата за использование веб-роли Windows Azure начисляется по количеству часов работы сервера. Отсчет этого времени начинается с момента развертывания приложения, даже если оно не запущено.

Ниже показано, как остановить и удалить приложение.

В окне Windows PowerShell выполните следующий командлет, чтобы остановить развернутую в предыдущем разделе службу:

PS C:\node\tasklist\WebRole1> Stop-AzureService

Остановка службы может занять несколько минут. Когда служба будет остановлена, появится соответствующее уведомление.

clip_image026

Чтобы удалить службу, вызовите следующий командлет:

PS C:\node\tasklist\WebRole1> Remove-AzureService contosotasklist

Когда появится запрос системы, нажмите клавишу Y для удаления службы.

Удаление службы может занять несколько минут. Когда служба будет удалена, появится соответствующее уведомление.

clip_image027