Building Cloud-Native Applications With Node-Js and Azure
Building Cloud-Native Applications With Node-Js and Azure
Building cloud-
native applications
with Node.js
and Azure
ii
PUBLISHED BY
Microsoft Press
A division of Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-6399
This book is provided “as-is” and expresses the author’s views and
opinions. The views, opinions and information expressed in this book,
including URL and other Internet website references, may change
without notice.
Some examples depicted herein are provided for illustration only and are
fictitious. No real association or connection is intended or should
be inferred.
08
Chapter 3 / Principles for architecting 68
your cloud-native applications Summary
09 Sample architecture
11 Before you get started
12
Chapter 4 / Build the app
13 Create a Node.js web app in Azure App Service on Linux
14 Before you begin
14 Get set up
18 Build and deploy
21 Update and manage
21 Manage your new Azure web app
24 Deploy an Azure Container Service (AKS) cluster
25 Get set up
26 Deploy and test
30 Finish up
30 Next steps
February Introduction 1
2018
This e-book 01 /
The basics of cloud-native applications and
presents a Node.js
structured 02 /
The benefits of cloud-native applications
building 03 /
Principles for architecting your cloud-native
cloud-native 04 /
How to build a cloud-native application
Node.js and
cloud-native
applications are
changing the
way developers
build
February Introduction 3
2018
monoliths,
Applications scale horizontally, adding new
instances as demand requires.
services / multi-threaded
/ always-on
/ occassional bug updates
/ manual management
/ monolithic, centralized
In the simplest way to describe it, Node.js This makes Node.js a natural for the
is server-side JavaScript. It’s non-blocking cloud, with its anywhere access and need
and event-driven; thanks to its event for speed. With Azure, which is built to
loop, it is optimized for handling support many architectures (including
asynchronous I/O, such as calls to microservices), databases, and services,
databases or external services, two very as well as having support for containers,
common operations in modern web Node.js is all the more powerful. For
apps. And, because it’s JavaScript, it’s fast example, on Azure it’s easy to add identity
and flexible to use with other types of and access management through Azure
code. JavaScript was originally designed Active Directory, vision and speech
as a language only for client-side web capabilities with Azure Cognitive Services,
applications, but Node.js allows for server- or data insights through Azure Data Lake
side development, making it one of the Analytics – just to name a few of the
most popular programming languages. many examples.
Node.js allows web developers to expand
their creative potential by creating
servers, command-line tools, and desktop
applications. Using asynchronous I/O, the
server can do more than one thing at a
time, a key requirement for real-time apps
like chat, games and live statistics.
February The benefits of cloud-native for Node.js 6
2018 development
cloud-native
operating systems, tools, services, and
databases. Because of this, Node.js
applications
developers can connect to the functionality
they need to support their applications:
databases, identity providers, cognitive
with Node.js services, etc.
Reliability
As more and more applications are being Azure offers a large variety of hosting
developed in the cloud, agile practices have options, including Linux and Kubernetes.
emerged. Agile development promotes With containers like Docker you can
small, well planned, iterations by highly develop new features and functionality
collaborative teams, resulting in continuous within the production environment, but
delivery. The pillars of agile methodology isolate them so that you can test and roll
likely fit well with why you chose to work out new features or fixes with confidence.
with Node.js in the first place.
Some of the greatest benefits of working
Speed in the cloud are the monitoring and
Deliver the responsiveness users demand. analytics capabilities. By tracking costs
Because Node.js runs on the Chrome V8 and efficiencies of your work, you can
engine, which is optimized for speed, and understand what is working well, and make
because of its asynchronous processing, better decisions. This will also allow you to
Node.js apps are very fast. With Node.js, simplify your environment and free
speed is also about development agility, up resources.
which using JavaScript enables. Lastly,
with around half a million modules (and
counting) on NPM, the Node.js Package
Manager, developers can easily integrate
libraries for many common tasks.
February Principles for architecting your 8
2018 cloud-native application
and choose what and choose the number and kind of worker
nodes you want, and Azure takes care
CDN
Azure Region
Web Apps
on Linux
Download the full Cloud Native Application with Node.js and Azure Guide at aka.ms/architectureguide
Azure DB for MySQL and PostgreSQL
Visit the https://docs.microsoft.com/en-us/javascript/azure to find the latest technicalBlob Storage
guidance, developer tools, code
amples and quickstart guides to help you build your next Node.js project on Azure.
In addition to installing them on a Virtual Lastly, Azure Blob Storage is a massively
Machine, with Azure you can run MySQL scalable object storage. Your application
or PostgreSQL, two popular relational can use it to store static assets, images,
databases, as fully-managed services too. cached data, and anything unstructured, in
a simple and cost-effective way. Now that
Redis Cache we have introduced the components you
Azure Redis Cache offers the popular Redis will be working with, let’s get familiar with
in-memory key-value storage as a fully how to build and deploy a simple Node.js
managed service. web app in Azure.
February Principles for architecting your 11
2018 cloud-native application
Chapter 4 / 01 /
Create a Node.js web app in Azure App
Service on Linux
03 /
Azure Cosmos DB: Migrate an existing
Node.js Mongo DB web app
04 /
Azure Database for MySQL: Use Node.js to
connect and query data
05 /
How to use Azure Redis Cache with Node.js
06 /
How to use Blob storage from Node.js
February Build the app / Create a Node.js web app 13
2018 in Azure App Service on Linux
In a terminal window on your machine, clone the sample app repository to your local machine by
running the following command.
Use this terminal window to run all the commands in this example.
Change to the directory that contains the sample code.
cd nodejs-docs-hello-world
Get set up
Now that you have what you need, there are a few tasks to do before you build your app.
npm start
You’ll see the Hello World message from the sample app displayed in the page.
This button launches an interactive shell that you can use to run the steps in this topic:
A deployment user is required for FTP and local Git deployment to a web app. The user name and
password are account level. They are different from your Azure subscription credentials.
February Build the app / Create a Node.js web app 16
2018 in Azure App Service on Linux
In the following command, replace <username> and <password> with a new user name and
password. The user name must be unique. The password must be at least eight characters long, with
two of the following three elements: letters, numbers, symbols.
You might get an error at this point. Use the following guidance:
If you get a ‘Bad Request’. Details: 400 error, use a stronger password.
You only need to create this deployment user once. You can use it for all your Azure deployments.
NOTE
Record the user name and password. You need them to deploy the web app later.
A resource group is a logical container into which Azure resources like web apps, databases, and
storage accounts are deployed and managed.
The following example creates a resource group named myResourceGroup in the West Europe
location.
As a best practice, create your resource group and the resources in a region near you. To see all
supported locations for App Service plans, run the az appservice list-locations command.
February Build the app / Create a Node.js web app 17
2018 in Azure App Service on Linux
An App Service plan specifies the location, size, and features of the web server farm that hosts your
app. You can save money when hosting multiple apps by configuring the web apps to share a single
App Service plan.
The following example creates an App Service plan named myAppServicePlan in the Standard
pricing tier with one instance (S1), and in a Linux container:
When you have created the App Service plan, the Azure CLI shows information similar to the
following example:
{
"adminSiteName": null,
"appServicePlanName": "myAppServicePlan",
"geoRegion": "West Europe",
"hostingEnvironmentProfile": null,
"id": "/subscriptions/0000-0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
"kind": "app",
"location": "West Europe",
"maximumNumberOfWorkers": 1,
"name": "myAppServicePlan",
< JSON data removed for brevity. >
"targetWorkerSizeId": 0,
"type": "Microsoft.Web/serverfarms",
"workerTierName": null
}
February Build the app / Create a Node.js web app 18
2018 in Azure App Service on Linux
The runtime in the following command is set to NODE|6.9. To see all supported runtimes, run
az webapp list-runtimes.
az webapp create \
--resource-group myResourceGroup \
--plan myAppServicePlan \
--name <app_name> \
--runtime "NODE|6.9" \
--deployment-local-git
When you have created the web app, the Azure CLI shows output similar to the following example:
The URL of the Git remote is shown in the deploymentLocalGitUrl property, with the format
NOTE
Browse to your newly created web app. Replace <app name> with a unique app name.
http://<app name>.azurewebsites.net
Push to the Azure remote to deploy your app with the following command. When prompted for a
password, make sure that you enter the password you created in Configure a deployment user, not
the password you use to log in to the Azure portal.
http://<app_name>.azurewebsites.net
The Node.js sample code is running in a web app with built-in image.
Congratulations! You've deployed your first Node.js app to App Service on Linux.
February Build the app / Create a Node.js web app 21
2018 in Azure App Service on Linux
response.end("Hello Azure!");
Commit your changes in Git, and then push the code changes to Azure.
Once deployment has completed, switch back to the browser window that opened in the Browse to
the app step, and hit refresh.
You see your web app’s Overview page. Here, you can perform basic management tasks like browse,
stop, start, restart, and delete.
In the left menu, there are different pages for configuring your app.
February Build the app / Create a Node.js web app 23
2018 in Azure App Service on Linux
Clean up resources
To clean up your resources, run the following command:
Now that you have created the front end, we can look at the back end of your application.
February Build the app / Deploy an Azure 24
2018 Container Service (AKS) cluster
In this example, you will deploy an AKS cluster using the Azure CLI. You will then run a simple
Todo application written in Node.js, which stores data on the client using HTML5 local storage.
Once completed, you can access the application over the internet.
This example assumes a basic understanding of Kubernetes concepts, for detailed information on
Kubernetes see the Kubernetes documentation.
Get set up
Launch Azure Cloud Shell
Click the Cloud Shell button on the menu in the upper-right of the Azure portal.
After registering, you are now ready to create a Kubernetes cluster with AKS.
February Build the app / Deploy an Azure 26
2018 Container Service (AKS) cluster
Use the following example to create a resource group named myResourceGroup in the Central US
location.
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup",
"location": "centralus",
"managedBy": null,
"name": "myResourceGroup",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null
}
az aks create \
--resource-group myResourceGroup \
--name myK8sCluster \
--node-count 1 \
--generate-ssh-keys
After several minutes, the command completes and returns JSON-formatted information about
the cluster.
If you're using Azure Cloud Shell, kubectl is already installed. If you want to install it locally, run the
following command.
February Build the app / Deploy an Azure 27
2018 Container Service (AKS) cluster
az aks install-cli
Run the following command to configure kubectl to connect to your Kubernetes cluster. This step
downloads credentials and configures the Kubernetes CLI to use them.
To verify the connection to your cluster, use the kubectl get command to return a list of the
cluster nodes.
Output:
Create a Kubernetes manifest file, called todo-app.yaml , by copying in the following YAML code.
If you are working in Azure Cloud Shell, you can create this file using vi or nano as if working on a
virtual or physical system.
February Build the app / Deploy an Azure 28
2018 Container Service (AKS) cluster
apiVersion: v1
kind: Service
metadata:
name: web
labels:
name: web
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 3000
protocol: TCP
selector:
name: web
---
apiVersion: v1
kind: ReplicationController
metadata:
labels:
name: web
name: web-controller
spec:
replicas: 2
selector:
name: web
template:
metadata:
labels:
name: web
spec:
containers:
- image: nodeebookdemo/nodejs-todo-sample
name: web
ports:
- containerPort: 3000
name: http-server
Output:
To monitor progress, use the kubectl get service command with the --watch argument.
Once the EXTERNAL-IP address has changed from pending to an IP address, use
Ctrl+C to stop the kubectl watch process.
You can now browse to the external IP address to see the Todo App.
February Build the app / Deploy an Azure 30
2018 Container Service (AKS) cluster
Finish up
Delete cluster
When you no longer need the cluster, you can use the az group delete command to remove the
resource group, container service, and all related resources.
In this example, you used pre-created container images to create a Kubernetes deployment. You can
get the related application code, Dockerfile, and Kubernetes manifest file on GitHub.
https://github.com/NodeEbookDemo/nodejs-todo-sample
Next steps
Now that you know about applications let's talk about the data.
February Build the app / Azure Cosmos DB: Migrate 31
2018 an existing Node.js Mongo DB web app
web app
February Build the app / Azure Cosmos DB: Migrate 32
2018 an existing Node.js Mongo DB web app
This example demonstrates how to use an existing app written in Node.js and designed to use
MongoDB, and connect it to your Azure Cosmos DB database, which supports MongoDB client
connections. In other words, your Node.js application only knows that it's connecting to a database
using MongoDB APIs. It is transparent to the application that the data is stored in Azure Cosmos DB.
When you are done, you will have a MEAN application (MongoDB, Express, Angular, and Node.js)
running on Azure Cosmos DB.
Get set up
Clone the sample application
Open a git terminal window, such as git bash, and cd to a working directory.
Run the following commands to clone the sample repository. This sample repository contains the
default MEAN.js application.
February Build the app / Azure Cosmos DB: Migrate 33
2018 an existing Node.js Mongo DB web app
cd mean
npm install
npm start
The application will try to connect to a MongoDB source and fail. Exit the application when the
output returns "[MongoError: connect ECONNREFUSED 127.0.0.1:27017]".
The following example creates a resource group in the West Europe region. Choose a unique name
for the resource group.
In the following command, substitute your own unique Azure Cosmos DB account name where you
see the <cosmosdb-name> placeholder. This unique name will be used as part of your Azure
Cosmos DB endpoint ( https://<cosmosdb-name>.documents.azure.com/ ), so the name needs to
be unique across all Azure Cosmos DB accounts in Azure.
When you have created the Azure Cosmos DB, the Azure CLI shows information similar to the
following example.
{
"databaseAccountOfferType": "Standard",
"documentEndpoint": "https://<cosmosdb-name>.documents.azure.com:443/",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myResourceGroup/providers/Microsoft.Document
DB/databaseAccounts/<cosmosdb-name>",
"kind": "MongoDB",
"location": "West Europe",
"name": "<cosmosdb-name>",
"readLocations": [
{
"documentEndpoint": "https://<cosmosdb-name>-westeurope.documents.azure.com:443/",
"failoverPriority": 0,
"id": "<cosmosdb-name>-westeurope",
"locationName": "West Europe",
"provisioningState": "Succeeded"
}
],
"resourceGroup": "myResourceGroup",
"type": "Microsoft.DocumentDB/databaseAccounts",
"writeLocations": [
{
"documentEndpoint": "https://<cosmosdb-name>-westeurope.documents.azure.com:443/",
"failoverPriority": 0,
"id": "<cosmosdb-name>-westeurope",
"locationName": "West Europe",
"provisioningState": "Succeeded"
}
]
}
Replace the content of this file with the following code. Be sure to also replace the two
<cosmosdb-name> placeholders with your Azure Cosmos DB account name.
'use strict';
module.exports = {
db: {
uri: 'mongodb://<cosmosdb-name>:<primary_master_key>@<cosmosdb-name>.documents.azure.com:10255/
mean-dev?ssl=true&sslverifycertificate=false'
}
};
az cosmosdb list-keys \
--name <cosmosdb-name> \
--resource-group myResourceGroup \
--query "primaryMasterKey"
"RUayjYjixJDWG5xTqIiXjC..."
npm start
A console message should indicate that the development environment is up and running.
Navigate to http://localhost:3000 in a browser. Click Sign Up in the top menu and try to create two
dummy users.
February Build the app / Azure Cosmos DB: Migrate 36
2018 an existing Node.js Mongo DB web app
The MEAN.js sample application stores user data in the database. If MEAN.js automatically signs into
the created user, then your Azure Cosmos DB connection is working.
2. When your Cosmos DB account blade opens, select your Cosmos DB account.
4. Expand your collection in the Collections pane, and then you can view the documents in the
collection, query the data, and even create and run stored procedures, triggers, and UDFs.
February Build the app / Azure Cosmos DB: Migrate 37
2018 an existing Node.js Mongo DB web app
You may have noticed that the configuration file that you changed earlier is for the development
environment ( /config/env/local-development.js ). When you deploy your application to App
Service, it will run in the production environment by default. So now, you need to make the same
change to the respective configuration file.
In the db object, replace the value of uri as show in the following example. Be sure to replace the
placeholders as before.
'mongodb://<cosmosdb-name>:<primary_master_key>@<cosmosdb-name>.documents.azure.com:10255/
mean?ssl=true&sslverifycertificate=false',
NOTE
git add .
git commit -m "configured MongoDB connection string"
Clean up resources
If you're not going to continue to use this app, delete all resources created by this example in the
Azure portal with the following steps:
1. From the left-hand menu in the Azure portal, click Resource groups and click the name of
the resource you created.
2. On your resource group page, click Delete. Type the name of the resource to delete in the text
box, and click Delete.
February Build the app / Azure Cosmos DB: Migrate 38
2018 an existing Node.js Mongo DB web app
Next steps
In this example, you've learned how to create an Azure Cosmos DB account and create a MongoDB
collection using the Data Explorer. You can now migrate your MongoDB data to Azure Cosmos DB.
If your application uses a relational database you can look at using MySQL. The same instructions
discussed below will also be applicable to PostgreSQL with some minor changes.
February Build the app / Azure Database MySQL: 39
2018 Use Node.js to connect and query data
connect and
query data
February Build the app / Azure Database MySQL: 40
2018 Use Node.js to connect and query data
Get set up
This quickstart uses the resources created in either of these guides as a starting point:
In the folder containing an existing Node.js app, add the mysql2 NPM package:
Prepare to connect
1. Paste the JavaScript code into text files, and then save it into a project folder with file extension .js
such as C:\nodejsmysql\createtable.js or /home/username/nodejsmysql/createtable.js.
2. Launch the command prompt or bash shell, and then change directory into your project folder
cd nodejsmysql.
3. To run the application, type the node command followed by the file name, such as node
createtable.js.
4. On Windows, if the node application is not in your environment variable path, you may need to
use the full path to launch the node application, such as node createtable.js.
Replace the host , user , password , and database parameters with the values that you
specified when you created the server and database.
var config =
{
host: 'myserver4demo.mysql.database.azure.com',
user: 'myadmin@myserver4demo',
password: 'your_password',
database: 'quickstartdb',
port: 3306,
ssl: true
};
conn.connect(
function (err) {
if (err) {
console.log("!!! Cannot connect !!! Error:");
throw err;
}
else
{
console.log("Connection established.");
queryDatabase();
}
});
function queryDatabase(){
conn.query('DROP TABLE IF EXISTS inventory;', function (err, results, fields) {
if (err) throw err;
console.log('Dropped inventory table if existed.');
})
conn.query('CREATE TABLE inventory (id serial PRIMARY KEY, name VARCHAR(50), quantity INTEGER);',
function (err, results, fields) {
if (err) throw err;
console.log('Created inventory table.');
})
conn.query('INSERT INTO inventory (name, quantity) VALUES (?, ?);', ['banana', 150],
function (err, results, fields) {
if (err) throw err;
else console.log('Inserted ' + results.affectedRows + ' row(s).');
})
conn.query('INSERT INTO inventory (name, quantity) VALUES (?, ?);', ['orange', 154],
function (err, results, fields) {
if (err) throw err;
console.log('Inserted ' + results.affectedRows + ' row(s).');
})
conn.query('INSERT INTO inventory (name, quantity) VALUES (?, ?);', ['apple', 100],
function (err, results, fields) {
if (err) throw err;
console.log('Inserted ' + results.affectedRows + ' row(s).');
})
conn.end(function (err) {
if (err) throw err;
else console.log('Done.')
});
};
February Build the app / Azure Database MySQL: 43
2018 Use Node.js to connect and query data
Read data
Use the following code to connect and read the data by using a SELECT SQL statement.
• Use the mysql.createConnection() method to interface with the MySQL server
• Use the connect() function to establish the connection to the server
• Use the query() function to execute the SQL query against MySQL database
• Use the results array to hold the results of the query
Replace the host , user , password , and database parameters with the values that you
specified when you created the server and database.
var config =
{
host: 'myserver4demo.mysql.database.azure.com',
user: 'myadmin@myserver4demo',
password: 'your_password',
database: 'quickstartdb',
port: 3306,
ssl: true
};
conn.connect(
function (err) {
if (err) {
console.log("!!! Cannot connect !!! Error:");
throw err;
}
else {
console.log("Connection established.");
readData();
}
});
function readData(){
conn.query('SELECT * FROM inventory',
function (err, results, fields) {
if (err) throw err;
else console.log('Selected ' + results.length + ' row(s).');
for (i = 0; i < results.length; i++) {
console.log('Row: ' + JSON.stringify(results[i]));
}
console.log('Done.');
})
conn.end(
function (err) {
if (err) throw err;
else console.log('Closing connection.')
});
};
February Build the app / Azure Database MySQL: 44
2018 Use Node.js to connect and query data
Update data
Use the following code to connect and read the data by using an UPDATE SQL statement.
• Use the mysql.createConnection() method to interface with the MySQL server
• Use the connect() function to establish the connection to the server
• Use the query() function to execute the SQL query against MySQL database
• Use the results array to hold the results of the query
Replace the host , user , password , and database parameters with the values that you
specified when you created the server and database.
var config =
{
host: 'myserver4demo.mysql.database.azure.com',
user: 'myadmin@myserver4demo',
password: 'your_password',
database: 'quickstartdb',
port: 3306,
ssl: true
};
conn.connect(
function (err) {
if (err) {
console.log("!!! Cannot connect !!! Error:");
throw err;
}
else {
console.log("Connection established.");
updateData();
}
});
function updateData(){
conn.query('UPDATE inventory SET quantity = ? WHERE name = ?', [200, 'banana'],
function (err, results, fields) {
if (err) throw err;
else console.log('Updated ' + results.affectedRows + ' row(s).');
})
conn.end(
function (err) {
if (err) throw err;
else console.log('Done.')
});
};
February Build the app / Azure Database MySQL: 45
2018 Use Node.js to connect and query data
Delete data
Use the following code to connect and read the data by using an DELETE SQL statement.
• Use the mysql.createConnection() method to interface with the MySQL server
• Use the connect() function to establish the connection to the server
• Use the query() function to execute the SQL query against MySQL database
• Use the results array to hold the results of the query
Replace the host , user , password , and database parameters with the values that you
specified when you created the server and database.
var config =
{
host: 'myserver4demo.mysql.database.azure.com',
user: 'myadmin@myserver4demo',
password: 'your_password',
database: 'quickstartdb',
port: 3306,
ssl: true
};
conn.connect(
function (err) {
if (err) {
console.log("!!! Cannot connect !!! Error:");
throw err;
}
else {
console.log("Connection established.");
deleteData();
}
});
function deleteData(){
conn.query('DELETE FROM inventory WHERE name = ?', ['orange'],
function (err, results, fields) {
if (err) throw err;
else console.log('Deleted ' + results.affectedRows + ' row(s).');
})
conn.end(
function (err) {
if (err) throw err;
else console.log('Done.')
});
};
February Build the app / Azure Database MySQL: 46
2018 Use Node.js to connect and query data
Next steps
Now that we've implemented databases in our applications, we can include Redis Cache to improve
the performance of our services. Redis Cache is based on the open source Redis project. It's a fast,
in-memory, key-value store that can be used to cache data from the database or from other sources.
February Build the app / How to use Azure Redis 47
2018 Cache with Node.js
Get set up
Install node_redis:
This example uses node_redis. For examples of using other Node.js clients, see the individual
documentation for the Node.js clients listed at Node.js Redis clients.
In the New Redis Cache blade, specify the desired configuration for the cache.
February Build the app / How to use Azure Redis 50
2018 Cache with Node.js
• In DNS name, enter a unique cache name to use for the cache endpoint. The cache name
must be a string between 1 and 63 characters and contain only numbers, letters, and the
- character. The cache name cannot start or end with the - character, and consecutive -
characters are not valid.
• For Subscription, select the Azure subscription that you want to use for the cache. If your
account has only one subscription, it will be automatically selected and the Subscription
drop-down will not be displayed.
• Use Location to specify the geographic location in which your cache is hosted. For the best
performance, Microsoft strongly recommends that you create the cache in the same region
where yourapplication is deployed.
• Use Pricing tier to select the desired cache size and features.
• Redis cluster allows you to create caches larger than 53 GB and to shard data across multiple
Redis nodes. For more information, see How to configure clustering for a Premium Azure
Redis Cache.
• Redis persistence offers the ability to persist your cache to an Azure Storage account. For
instructions on configuring persistence, see How to configure persistence for a Premium
Azure Redis Cache.
• Virtual Network provides enhanced security and isolation by restricting access to your cache
to only those clients within the specified Azure Virtual Network. You can use all the features
of VNet such as subnets, access control policies, and other features to further restrict access
to Redis. For more information, see How to configure Virtual Network support for a Premium
Azure Redis Cache.
• By default, non-SSL access is disabled for new caches. To enable the non-SSL port, check
Unblock port 6379 (not SSL encrypted); this is optional.
February Build the app / How to use Azure Redis 51
2018 Cache with Node.js
Once the new cache options are configured, click Create. It can take a few minutes for the cache to
be created. To check the status, you can monitor the progress on the startboard. After the cache has
been created, your new cache has a Running status and is ready for use with default settings.
Retrieve host name, ports, and access keys using the Azure Portal
To retrieve host name, ports, and access keys using the Azure Portal, browse to your cache in the
Azure portal and click Access keys and Properties in the Resource menu.
February Build the app / How to use Azure Redis 52
2018 Cache with Node.js
Retrieve host name, ports, and access keys using Azure CLI
To retrieve the host name and ports using Azure CLI 2.0 you can call az redis show, and to retrieve
the keys you can call az redis list-keys. The following script calls these two commands and prints the
hostname, ports, and keys to the console.
February Build the app / How to use Azure Redis 53
2018 Cache with Node.js
#!/bin/bash
# Retrieve the hostname, ports, and keys for contosoCache located in contosoGroup
# Retrieve the hostname and ports for an Azure Redis Cache instance
redis=($(az redis show --name contosoCache --resource-group contosoGroup --query [hostName,enableNonSslPort,port,sslPort] --output tsv))
keys=($(az redis list-keys --name contosoCache --resource-group contosoGroup --query [primaryKey,secondaryKey] --output tsv))
For more information about this script, see Get the hostname, ports, and keys for Azure Redis Cache.
{servername: '<name>.redis.cache.windows.net'}});
The non-SSL port is disabled for new Azure Redis Cache instances. If you are using a different client that
NOTE
{servername: '<name>.redis.cache.windows.net'}});
console.log(reply);
});
console.log(reply);
});
Output:
OK
value
Next steps
• Enable cache diagnostics so you can monitor the health of your cache
• Read the official Redis documentation
Finally, let's explore how we can use Azure Blob Storage. Many applications need an object storage
where they can store any kind of unstructured data, including documents, photos, and attachments.
Using the Azure Storage SDK for Node.js developers can use Azure Blob Storage to store these files
quickly and in a cost-effective way, using the Azure Storage SDK for Node.js.
February Build the app / How to use Blob storage 55
2018 from Node.js
• Storage Account: Use a storage account for All access to Azure Storage. You can use a General-
purpose storage account or a Blob storage account, which is specialized for storing objects/
blobs. See About Azure storage accounts for more information.
• Container: A container provides a grouping of a set of blobs. All blobs must be in a container.
An account can contain an unlimited number of containers. A container can store an unlimited
number of blobs. (The container name must be lowercase.)
• Blob: A file of any type and size. Azure Storage offers three types of blobs: block blobs, page
blobs, and append blobs. For this exercise we are concerned only with block and append blobs.
• Block blobs are ideal for storing text or binary files, such as documents and media files. A
single block blob can contain up to 50,000 blocks of up to 100 MB each, for a total size of
slightly more than 4.75 TB (100 MB X 50,000).
• Append blobs are similar to block blobs in that they are made up of blocks, but they
are optimized for append operations, so they are useful for logging scenarios. A single
append blob can contain up to 50,000 blocks of up to 4 MB each, for a total size of
slightly more than 195 GB (4 MB X 50,000).
• Page blobs can be up to 8 TB in size, and are more efficient for frequent read/write
operations. Azure Virtual Machines use page blobs as OS and data disks.
February Build the app / How to use Blob storage 57
2018 from Node.js
For details about naming containers and blobs, see Naming and Referencing Containers, Blobs, and
Metadata.
1. Use a command-line interface to navigate to the folder where you created your sample
application.
2. Type npm install --save azure-storage in the command window. Output from the command is
similar to the following code example.
[email protected] node_modules\azure-storage
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected]
+-- [email protected] ([email protected], [email protected], [email protected], [email protected])
+-- [email protected] ([email protected])
+-- [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected], tun-
[email protected], [email protected], [email protected], [email protected], [email protected], [email protected], [email protected],
[email protected], [email protected], [email protected], [email protected], [email protected])
Using Notepad or another text editor, add the following to the top of the file of the application
where you intend to use storage:
connect to your Azure storage account. If these environment variables are not set, you must specify
the account information when calling createBlobService.
You can access a blob anonymously by using createBlobServiceAnonymous and providing the host address.
NOTE
Every blob in Azure storage must reside in a container. The container forms part of the blob name.
For example, mycontainer is the name of the container in these sample blob URIs:
https://storagesample.blob.core.windows.net/mycontainer/blob1.txt
https://storagesample.blob.core.windows.net/mycontainer/photos/myphoto.jpg
A container name must be a valid DNS name, conforming to the following naming rules:
1. Container names must start with a letter or number, and can contain only letters, numbers, and
the dash (-) character.
2. Every dash (-) character must be immediately preceded and followed by a letter or number;
consecutive dashes are not permitted in container names.
Important: the name of a container must always be lowercase. If you include an upper-case letter in a
NOTE
container name, or otherwise violate the container naming rules, you may receive a 400 error (Bad Request).
To create a new container, use createContainerIfNotExists. The following code example creates a
new container named 'mycontainer':
If the container is newly created, result.created is true. If the container already exists,
result.created is false. response contains information about the operation, including the ETag
information for the container.
Container security
By default, new containers are private and you cannot access them anonymously. To make the
container public so that you can access it anonymously, you can set the container’s access level to
blob or container.
• Blob - allows anonymous read access to blob content and metadata within this container, but
not to container metadata such as listing all blobs within a container
• Container - allows anonymous read access to blob content and metadata as well as
container metadata
The following code example demonstrates setting the access level to blob:
Alternatively, you can modify the access level of a container by using setContainerAcl to specify the
access level. The following code example changes the access level to container:
The result contains information about the operation, including the current ETag for the container.
Filters
You can apply optional filtering operations to operations performed using BlobService. Filtering
operations can include logging, automatically retrying, etc. Filters are objects that implement a
method with the signature:
After doing its preprocessing on the request options, the method needs to call "next", passing a
callback with the following signature:
In this callback, and after processing the returnObject (the response from the request to the server),
the callback needs to either invoke next if it exists to continue processing other filters or simply
invoke finalCallback to end the service invocation.
Two filters that implement retry logic are included with the Azure SDK for Node.js,
ExponentialRetryPolicyFilter and LinearRetryPolicyFilter. The following creates a BlobService
object that uses the ExponentialRetryPolicyFilter:
Block blobs
Use the following to upload data to a block blob:
• createBlockBlobFromLocalFile - creates a new block blob and uploads the contents of a file
• createBlockBlobFromStream - creates a new block blob and uploads the contents of a
stream
• createBlockBlobFromText - creates a new block blob and uploads the contents of a string
• createWriteStreamToBlockBlob - creates a new block blob and then provides a stream to
write to it
The following code example uploads the contents of the test.txt file into myblob.
Append blobs
Use the following to upload data to a new append blob:
The following code example uploads the contents of the test.txt file into myappendblob.
• appendFromLocalFile - creates a new append blob and uploads the contents of a file
• appendFromStream - creates a new append blob and uploads the contents of a stream
• appendFromText - creates a new append blob and uploads the contents of a string
• appendBlockFromStream - creates a new append blob and then provides a stream to
write to it
• createWriteStreamToNewApendBlob - creates a new append blob and then provides a
stream to write to it
appendFromXXX APIs will do some client-side validation to fail fast to avoid unnecessary server calls.
NOTE
appendBlockFromXXX won’t.
The following code example uploads the contents of the test.txt file into myappendblob.
Download blobs
Use the following to download data from a blob:
The following code example demonstrates using getBlobToStream to download the contents of
the myblob blob and store it to the output.txt file by using a stream:
var fs = require('fs');
blobSvc.getBlobToStream('mycontainer', 'myblob', fs.createWriteStream('output.txt'), function(error, result, response){
if(!error){
// blob retrieved
}
});
The result contains information about the blob, including ETag information.
Delete a blob
Finally, to delete a blob, call deleteBlob. The following code example deletes the blob named
myblob.
• Etag - provides a way to detect that the blob or container has been modified by another
process
• Lease - provides a way to obtain exclusive, renewable, write or delete access to a blob for a
period of time.
ETags
Use ETags if you need to allow multiple clients or instances to write to the block Blob or page Blob
simultaneously. The ETag allows you to determine if the container or blob was modified since you
initially read or created it, which allows you to avoid overwriting changes committed by another
client or process.
February Build the app / How to use Blob storage 64
2018 from Node.js
You can set ETag conditions by using the optional options.accessConditions parameter. The
following code example only uploads the test.txt file if the blob already exists and has the ETag value
contained by etagToMatch.
If the value was modified, it indicates that another client or instance modified the blob or container
since you obtained the ETag value.
Lease
You can acquire a new lease by using the acquireLease method, specifying the blob or container
that you wish to obtain a lease on. For example, the following code acquires a lease on myblob.
Subsequent operations on myblob must provide the options.leaseId parameter. The lease ID is
returned as result.id from acquireLease.
By default, the lease duration is infinite. You can specify a non-infinite duration (between 15 and 60 seconds)
NOTE
To remove a lease, use releaseLease. To break a lease, but prevent others from obtaining a new
lease until the original duration has expired, use breakLease.
February Build the app / How to use Blob storage 65
2018 from Node.js
While you can also allow anonymous access to blobs, shared access signatures allow you to provide more
NOTE
A trusted application such as a cloud-based service generates shared access signatures using the
generateSharedAccessSignature of the BlobService, and provides it to an untrusted or
semi-trusted application such as a mobile app. Shared access signatures are generated using a
policy, which describes the start and end dates during which the shared access signatures are valid,
as well as the access level granted to the shared access signatures holder.
The following code example generates a new shared access policy that allows the shared access
signatures holder to perform read operations on the myblob blob, and expires 100 minutes after the
time it is created.
var sharedAccessPolicy = {
AccessPolicy: {
Permissions: azure.BlobUtilities.SharedAccessPermissions.READ,
Start: startDate,
Expiry: expiryDate
},
};
A trusted application such as a cloud-based service generates shared access signatures using the
generateSharedAccessSignature of the BlobService, and provides it to an untrusted or
semi-trusted application such as a mobile app. Shared access signatures are generated using a
policy, which describes the start and end dates during which the shared access signatures are valid,
as well as the access level granted to the shared access signatures holder.
The following code example generates a new shared access policy that allows the shared access
signatures holder to perform read operations on the myblob blob, and expires 100 minutes after the
time it is created.
February Build the app / How to use Blob storage 66
2018 from Node.js
You must also provide the host information, as it is required when the shared access signatures
holder attempts to access the container.
The client application then uses shared access signatures with BlobServiceWithSAS to perform
operations against the blob. The following gets information about myblob.
Since the shared access signatures were generated with read-only access, if an attempt is made to
modify the blob, an error will be returned.
An ACL is implemented using an array of access policies, with an ID associated with each policy. The
following code example defines two policies, one for ‘user1’ and one for ‘user2’:
var sharedAccessPolicy = {
user1: {
Permissions: azure.BlobUtilities.SharedAccessPermissions.READ,
Start: startDate,
Expiry: expiryDate
},
user2: {
Permissions: azure.BlobUtilities.SharedAccessPermissions.WRITE,
Start: startDate,
Expiry: expiryDate
}
};
February Build the app / How to use Blob storage 67
2018 from Node.js
The following code example gets the current ACL for mycontainer, and then adds the new policies
using setBlobAcl. This approach allows:
Once the ACL is set, you can then create shared access signatures based on the ID for a policy. The
following code example creates new shared access signatures for 'user2':
Next steps
For more information related to this chapter, see the following resources.
a cloud-native Node.js:
application Documentation
Visit the Azure for Node.js Developers
Free Training
Explore our selection of free online training
courses for Node.js development on Azure
from Pluralsight.
Free Training
Subscribe to our Microsoft+Open Source
blog and follow @OpenAtMicrosoft on
Twitter to keep in touch and stay up to date
on the latest open source news and updates
at Microsoft.
https://azure.microsoft.com