Работа с хранилищем данных в облачном приложении 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.
Снимок экрана готового приложения приведен ниже.
Настройка учетных данных в файле 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>
Сохраните файл и закройте Блокнот.
Установка модулей
Для работы со службами хранилища 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 пока отсутствует, но мы скоро его создадим.
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.
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:
Добавление функциональности для создания задач
В этом разделе показано, как реализовать создание задач в приложении.
Добавление маршрута в Server.js
Добавьте в файл server.js приведенную ниже строку сразу за последней записью маршрута в /home, а затем сохраните изменения.
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 после первой строки экспорта модуля.
var uuid = require('node-uuid');
Добавление функциональности для создания задач в контроллере Home
Чтобы реализовать возможность создания задач, добавьте функцию newItem. Вставьте приведенный ниже код в файл home.js сразу за последней функцией и сохраните изменения.
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
В браузере отобразится следующая страница:
Заполните поля следующим образом: Item Name: «Создание задач», Item Category: «Сайт работает?» и Item Date: «12.02.2011». Затем нажмите Add item.
Элемент будет добавлен в таблицу задач хранилища Windows Azure и появится на экране, как показано на снимке экрана ниже.
Повторная публикация приложения в Windows Azure
Теперь, когда приложение полностью готово, осталось опубликовать его в Windows Azure, обновив старое развертывание в размещенной службе.
В окне Windows PowerShell вызовите следующий командлет, чтобы повторно развернуть размещенную службу на Windows Azure. При этом уже существующие настройки хранения и местоположения не изменятся.
PS C:\node\tasklist\WebRole1> Publish-AzureServiceProject -name myuniquename -location datacentername -launch
После завершения развертывания на экране отобразится примерно следующее:
Поскольку мы, как и в предыдущих примерах, использовали ключ -launch, после окончания развертывания автоматически запустится браузер и отобразит приложение в Windows Azure.
Остановка и удаление приложения
В некоторых случаях может понадобиться отключить развернутое приложение, чтобы сэкономить средства или освободить место под другие приложения.
Оплата за использование веб-роли Windows Azure начисляется по количеству часов работы сервера. Отсчет этого времени начинается с момента развертывания приложения, даже если оно не запущено.
Ниже показано, как остановить и удалить приложение.
В окне Windows PowerShell выполните следующий командлет, чтобы остановить развернутую в предыдущем разделе службу:
PS C:\node\tasklist\WebRole1> Stop-AzureService
Остановка службы может занять несколько минут. Когда служба будет остановлена, появится соответствующее уведомление.
Чтобы удалить службу, вызовите следующий командлет:
PS C:\node\tasklist\WebRole1> Remove-AzureService contosotasklist
Когда появится запрос системы, нажмите клавишу Y для удаления службы.
Удаление службы может занять несколько минут. Когда служба будет удалена, появится соответствующее уведомление.