构建 Node.js 和 MongoDB Web 服务
云是中性的所有语言。 云计算,它不应该不管您运行的应用程序是 Node.js、 ASP.NET、 Java 或 PHP,因为云计算提供一个现成的基础设施运行它们。 云的宗教是敏捷,以及灵活性允许您快速实施新的想法和日落在市场上不起作用的那些。 近年来,Node.js 已中流行一类新的开发者青睐的异步编程范式。 Node.js 是一个 JavaScript 运行时引擎生成客户端和服务器应用程序。 它包括一个异步 I/O 框架,可以帮助它处理数千个并发连接的最小 CPU 或内存开销在单个线程上。 这是一个受欢迎的神话 Node.js 是一个 Web 开发框架 ; 事实上,它是一个单线程运行时引擎的运行 JavaScript 代码。 它有一个模块化的体系结构,允许任何人构建和发布模块来处理特定任务如 Web 开发或访问 MongoDB 数据库。 例如,快递模板引擎是您可以下载作为一个模块在 Node.js 的 Web 应用程序框架。 核心 Node.js 引擎是建立在 c + + 在 Google V8 JavaScript 引擎,为 Chrome 浏览器设计的。 Node.js 支持在微软 Azure 网站,和微软也为使用 Azure Api 编程提供了开发工具和本机的 SDK。 那里是 Node.js 在 Azure 门户上的一个专用的开发人员中心 bit.ly/1iupElQ。
在这篇文章,看看你如何开发 Node.js 访问 MongoDB 数据库在云彩中,rest 风格的 Web 服务,以及如何将它部署到 Azure 的 Web 站点。
Node.js 基于异步开发模式,这意味着你让每个方法调用需要回调来接收响应。 虽然.NET 开发人员的传统上喜欢同步 (请求-响应) 方法调用,异步功能一直存在在 Microsoft.NET 框架中。 夹杂物新异步-等待在.NET 框架中的编程模型,异步应用程序已成为规范跨 Web 和移动应用程序。 在异步编程中,调用函数回调事件订阅,并提供一个委托来处理该响应。 回调函数被调用处理完成时。 它是像一封电子邮件比打个电话。
下面显示了简单的 Node.js Web 服务器返回一个字符串,当调用:
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type":
"text/plain"});
response.write("Hello MSDN");
response.end();
}).listen(8080);
请注意响应函数调用时触发一个 HTTP 请求事件。 这个函数用于加载的模块,类似于从.NET 框架中的程序集加载的命名空间。
很多的讨论和与 Node.js,ASP.NET 的宗教争论,但我不会去碰这一主题在这篇文章。 我的方法一直使用最好的工具为这份工作,和与你擅长做你最好的。
Node.js 请求处理
作为图 1 显示,Node.js 发动机启动一个线程来处理的并发客户端连接。 单线程已初始化,是没有开销用于处理请求的任何上升,因为线程快速委托向工作线程进行处理异步请求所需的初始化。
图 1 Node.js 请求-响应业务流程
如果 HTTP 请求包括一个长时间运行或 O 密集型的任务,如访问数据库或 Web 服务调用,它是在非阻塞的线程中异步执行。 长时间运行的任务一旦完成,工作线程向主线程作为回调返回的结果。 主线程然后向客户端返回结果。 进口常数的概念需要理解这里是单个接收线程总是可用于接收请求并不会保留忙着处理,因为处理委派给工作线程。
Node.js 核心组件
Node.js 由两个核心组件组成:
核心/内核:Node.js 的内核是写在 c + + 在 Google V8 JavaScript 引擎。 核心本身是单线程的是有能力之间的 Cpu 负载的均衡。 Node.js 是开源的你可以得到的源代码从 github.com/joyent/node。
功能模块:模块是类似于 NuGet 程序包在.NET 框架中。 Node.js 包管理器 (NPM) 是用于管理您的开发环境中的 Node.js 包的工具。 模块生成新的进程或线程不同 I/O 强度的任务。 最受欢迎的模块之间是 HTTP,MongoDB,快递 (Web 模板框架) 和 Socket.IO。 最受欢迎的模块的列表,请访问 nodejsmodules.org。
安装和 Node.js 在本地运行
在运行之前任何的 Node.js Web 站点在云彩中,我推荐尝试本地以获得满意的平台。 你可以安装和运行 Node.js 在 Windows 平台上只是以下三个步骤:
- 下载并安装 Node.js:Node.js Windows 安装程序可以下载并安装从 nodejs.org/#download。 安装程序将安装 Node.js 运行时和故宫。
- 创建一个简单的服务器:要在 Node.js 中创建一个 HTTP 服务器,打开您喜欢的文本编辑器,将复制的代码从图 1,并将该文件保存为 webserver.js。 前面显示的代码与为每个请求相同的字符串创建极简主义的 Web 服务器在端口 8080 上侦听和响应。
- 将 HTTP 服务器运行:最后,要运行服务器,打开命令提示符窗口,导航到保存的文件夹,您的 webserver.js 文件并键入以下内容:
>"C:\Program Files\nodejs\node.exe"webserver.js - 此命令将启动 Web 服务器,并可以通过导航到 http://localhost:8080 您的浏览器对其进行测试。 这个简单的服务器应该给你足够的信心去试用 Node.js 作为开发 Web 站点的选项。
在蔚蓝的 Web 站点上运行 Node.js
当我第一次用 Node.js 时,我决定以避免尽可能多的命令行。 我真的很看重过我的生活在 Visual Studio 中,您可以实现使用的是 IDE 的生产力。 幸运的是,微软已经投入在 WebMatrix,发展的有力工具开放性 Node.js 上 Windows 的应用程序。 Visual Studio 团队还发布了 Node.js 工具 Visual Studio (nodejstools.codeplex.com)。 对于本文的其余部分,我将使用 WebMatrix 作为我的主要开发工具。 从 WebMatrix,你可以安装 NPM 包,将网站发布到 Azure,和也在本地运行它们。 WebMatrix IIS 表达,它允许您在 IIS 上的 Node.js 应用程序宿主的也安装了 IISNode。 你可以得到更多的细节,关于在 IISNode github.com/tjanczuk/iisnode。
在构建一个完整的 rest 风格的 Web 服务之前, 看看你如何将一个简单的 Web 站点发布到 Azure 从 WebMatrix。
创建一个新的 Azure 网站 中所示,可以在从 Azure 门户,Azure 中创建新的 Web 站点 图 2。
图 2 创建一个新的 Azure 网站
门户网站将创建一个新的网站与您指定的区域的唯一名称。 该地区是重要的在同一个数据中心共同定位您的 Web 站点、 数据库和其他服务。 被控离开数据中心的数据。
创建一个表示 Web 站点快递是 Node.js Web 应用程序框架。 它遵循模型-视图-控制器 (MVC) 模式,因此,允许您建立建设 Node.js MVC Web 站点,以及 rest 风格的 Web 服务的路线。 您可以下载从快车 expressjs.com。
如果你爱在 Visual Studio.NET 开发,我建议去掌握 WebMatrix 开发 Node.js 的应用程序。 WebMatrix 3 包含一个有用的、 预建的快递模板。 打开它,并点击新 |模板库。 然后,Node.js 类别下,请选择快递网站模板,如中所示图 3。
指定的站点的名称,单击下一步要安装 IISNode 和表达的网站模板。
图 3 表达网站模板
我建造了早些时候的 Node.js 服务器不会运行是 Azure 网站上会因为 Azure 网站基础设施依赖于 IIS 上运行的 Web 站点。 因此,要运行一个 Node.js 的网站,我需要 IIS 和 IISNode 提供的 Node.js 之间的集成。
图 4 说明了创建由快递模板和 server.js 的源代码文件的文件结构。
图 4 快递文件结构
请注意,快递和路由模块会自动导入。 我将使用这些模块来构建 REST 服务。
本地 Web 站点运行以下我前面的建议,请单击 WebMatrix 来测试您的本地计算机上的 Web 站点上的运行按钮。 如果安装成功,你应该看到快递主页。
快递模板还将安装玉模板引擎。 玉是一种 HTML 模板引擎,用于建筑从快递框架生成的意见。 玉是要表达什么剃须刀是到 ASP.NET MVC。 因此,index.html 内容呈现从 /views/index.jade 和 /routes/index.js。 这些路线上设置 16、 17 和 server.js,30 行中所示图 4。 对玉模板引擎的详细信息,请访问玉 lang.com。
将 Web 网站发布到 Azure 现在,您已经构建本地快递的 Node.js Web 站点,让我们将它发布到 Azure。 单击在 WebMatrix 启动过程中的发布按钮。 导入您的 Web 站点的发布配置文件并按照发布向导中所示图 5。
图 5 将发布到微软 Azure
如果一切顺利,WebMatrix 会加载您互联网资源管理器中的 Web 站点。
在浏览器中的 URL 应该是 Azure 网站您发布到 Web 站点。 这是一个好的演示,它是多么容易开发和 Node.js Web 站点和 Web 服务部署到 Azure。 现在,我来看一下,看看 MongoDB。 我回来 Node.js 以后来构建 Web 服务。
MongoDB 概述
MongoDB 是一个开放的来源,包括了大部分的基础设施功能的关系数据库中,如复制、 分片、 索引和故障转移的可扩展性、 高性能、 面向文档的数据库。 MongoDB 还提供自动分片,并且具有内置的地图减少处理能力,不今天大多数关系数据库所提供。 关系数据库中存储系统在哪儿贵时代设计了。 将数据存储在关系格式允许开发人员优化的存储空间不会危及快速数据检索。 在今天的世界中,存储很便宜时相比来计算成本。 云计算,存储价格继续下降。 其结果是,保存和检索关系格式中的数据是比较昂贵的在云计算中存储它。 对连续数据交付的需求在上升,是更多应用程序,期待着您的数据存储的实时数据。 MongoDB 允许您保存对象和文档,而不把它们分解成关系组件。 这减少了应用程序,以及该数据库上的处理负载。
MongoDB 不是推荐需要深对象关系,因为它不设计来保持和检索对象和数据的关系联系起来,关系数据库是应用程序。 如果您的应用程序需要深厚的关系和 SQL 进行检索,然后使用关系数据库。 如果您的应用程序需要快速对象存储和检索,使用 MongoDB。 前面提到的使用这项工作的最佳工具。
资源调配 MongoDB 中 Azure
MongoDB 是可作为 Azure 存储区中加载项,您可以免费安装一个沙箱版本。 登录到您的 Azure 门户并从新安装 MongoDB (MongoLab) |商店 |加载项菜单,如图所示的图 6。
图 6 MongoDB 加载项从 MongoLab
在个性化加载项页面上,选择的沙盒版本,并请务必在您的 Web 站点,相同的区域中安装 MongoDB 实例中所示图 7。
图 7 配置 MongoDB
一旦安装完成,导航到加载项页并保存的已安装的数据库的连接字符串,如中所示图 8。 将使用的连接字符串,连接从您的 Node.js Web 服务。
图 8 为已安装的数据库的的连接字符串
MongoDB 现在运行在 Azure。 MongoLab (由 ObjectLabs 公司) 具有其自己专用的管理门户,您可以通过单击管理您的加载项链接查看。
您现在有一个 MongoDB 数据库运行在云中,并创建了一个空的 Node.js 模板。 若要完成应用程序,您需要填充的 MongoDB 数据库,并创建从该数据库中检索数据的 Web 服务。 这是云计算的标准软件开发。
MongoDB 连接安装 Node.js 先决条件
JSON 是一个一流的公民在 MongoDB 中,和,因此,补充了 Node.js。 因为 Web 服务将连接到 MongoDB,需要从新公共管理库安装 MongoDB Node.js 的最新驱动 (见图 9)。
MongoDB 的图 9 Node.js 驱动程序
MongoDB 连接信息获取存储在配置文件中。 Nconf 模块允许您从文件中读取配置信息 (请参见图 10)。
图 10 nconf 模块
一旦安装了 mongodb 和 nconf 的模块,您完成了所有的设置 Node.js 和 MongoDB 的发展环境的先决条件。
创建其他 Web 服务签名
若要创建其他 Web 服务,你首先定义依赖关系和路线在 server.js 中:
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path'),
pkgs=require('./routes/pkgs');
接下来,你定义的其他功能在 /routes/pkgs.js 文件中因为在前面的代码中,您将委托处理到入门模块的功能。 在路由文件夹中,创建名为 pkgs.js,用于定义 Web 服务操作,如中所示的文件图 11。
图 11 其余的操作签名
exports.findAll = function(req, res) {
res.send([{name:'app1'}, {name:'app2'}, {name:'app3'}]);
};
exports.findById = function(req, res) {
res.send({id:req.params.id,
name: "DisplayName", description: "description"});
};
exports.addPkg = function (req, res) {
res.send("Success");
};
exports.updatePkg = function (req, res) {
res.send("Success");
};
若要测试行动的基本运作,只是创建函数骨架返回静态数据。 您可以稍后添加数据库访问代码。 在 server.js,您刚刚创建的模块方法定义的对应的工艺路线方法:
app.get('/pkgs', pkgs.findAll);
app.get('/pkgs/:id', pkgs.findById);
app.post('/pkgs', pkgs.addPkg);
app.put('/pkgs/:id', pkgs.updatePkg);
如果你熟悉 ASP.NET Web API,你很快会明白这些路线以及它们映射到适当的实现类。 映射与路线宣言,任何请求到 /pkgs 将路由到在 pkgs.js 的功能之一。 随着 Web 服务的操作签名和定义在的地方,您可以测试如果路线通过运行该 Web 站点本地,以及在 Azure 工作正常。 要测试的 Url 如下:http://[Web 网站 URL] / 入门,http://[Web 网站 URL] / 入门/远程,和 http://[Web 的网站 Url] / 入门/1。 如果这些 Url 返回的预期值,路线,做工精细,你可以着手 MongoDB 一体化。
执行其余的 Web 服务操作
现在您需要实现的 Web 服务操作,以连接到 MongoDB 并检索数据。 四个步骤将实现这一点:
- 创建一个 config.json 文件,将 MongoDB 的连接字符串存储在它。
- 正在初始化 MongoDB 客户端。
- 用样本数据填充 MongoDB。 在此步骤中,该函数使 HTTP GET 调用到 http://storage.appsforazure.com/appsforazureobjectstest/servicepackages.json,并将检索到的数据存储到 MongoDB 实例。
- 用于检索和数据存储在 MongoDB 中的数据访问功能实现。
创建文件 config.json config.json 文件,这是类似于.NET app.config 但在 JSON 格式,存储您的配置信息。 将下面的名称-值对添加到新的文件:
{
"MONGOLAB_URI" :
"mongodb://nodeapps:xxxxxxxx.f.migd9GGB9Ck3M17jlkVCUVI-@ds027758.
mongolab.com:27758/nodeapps"
}
值是之前保存从 Azure 门户的 MongoDB 的连接字符串。
在 pkgs.js,你必须导入 nconf 模块读取的配置值:
var nconf = require('nconf');
nconf.env().file({ file: 'config.json' });
var connectionString = nconf.get("MONGOLAB_URI");
ConnectionString 变量然后可以由函数用于连接到 MongoDB 数据库。 请注意那 connectionString 声明作为一个全局变量在 pkgs.js 中,这样所有的函数都可以访问它。
初始化 MongoDB 客户端:要初始化 MongoDB 数据库的连接,你必须导入 mongodb 模块和调用连接方法,如中所示图 12。
图 12 连接到 MongoDB 数据库
var mongo = require('mongodb');
var MongoClient = mongo.MongoClient
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
console.log("Connected to 'pkgsdb' database");
db.collection('pkgs', { strict: true },
function (err, collection) {
if (err) {
console.log(
"The 'pkgsdb' collection doesn't exist.
Creating it with sample data...");
populateDB(db);
}
});
}
})
当连接成功时中的 db 变量图 12 包含该数据库的连接对象。 Db.collection 函数试图连接到名为 pkgs.的集合 如果不存在入门,通过调用 populateDB 函数来创建一个新。 在实际应用中,你不需要这样做,因为实际上会在运行应用程序之前创建集合。 (在 MongoDB 中的集合是分组的相关文件,类似于在一个关系数据库系统中的数据库表。
填充与样本数据 MongoDB 对于这篇文章,我作为样本数据可用的软件包从集合 dynamicdeploy.com。 在 populateDB 函数中,加载此集合以 JSON 格式从 http://storage.appsforazure.com/appsforazureobjectstest/servicepackages.json,如图所示的**图 13**。
图 13 填充数据库
var populateDB = function (db) {
var body = "";
var url =
"http://storage.appsforazure.com/appsforazureobjectstest/servicepackages.json";
http.get(url, function (res2) {
res2.on('data', function (chunk) {
body += chunk;
});
res2.on("end", function () {
var pkgs = JSON.parse(body)
db.collection('pkgs', function (err, collection) {
collection.insert(pkgs, { safe: true },
function (err, result) { });
});
});
res2.on("error", function (error) {
// You can log here further
})
});
请注意 JSON 是一个头等公民在 Node.js,所以您不需要导入任何模块解析 JSON 对象。 Collection.insert 函数在 MongoDB 在集合中插入整个 JSON 文档 (var 入门)。 MongoDB 在运行时确定对象的架构,使明智的决定,将它们存储。 在关系数据库中,你将不得不在它存储的任何数据之前,定义表的架构。 集合使您能够灵活地在运行时修改架构,只是通过改变的 JSON 对象的属性。 如果对象的属性更改,MongoDB 会自动应用这些更改的架构存储该对象之前。 这是用于构建应用程序,如社会和物联网的饲料,动态地更改数据类型的变化。
执行数据访问函数最后,您需要执行数据访问函数的 HTTP GET,邮政和放功能较早前宣布。 HTTP GET 函数映射到的 findById 和 findAll 功能在 Web 服务中,如图所示的图 14。
图 14 的查找功能
exports.findById = function (req, res) {
var id = req.params.id;
console.log('Retrieving pkg: ' + id);
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
db.collection('pkgs', function (err, collection) {
collection.findOne({ '_id': new BSON.ObjectID(id) },
function (err, item) {
res.send(item);
});
});
}
})
};
exports.findAll = function(req, res) {
MongoClient.connect(connectionString, function(err, db) {
if(err) throw err;
if(!err) {
db.collection('pkgs', function(err, collection) {
collection.find().toArray(function(err, items) {
res.send(items);
});
});
}
})
};
FindById 函数检索一个对象通过其 Id,而 findAll 函数检索的所有对象。 函数 collection.find和 collection.find 从检索结果的这些操作 MongoDB,分别。 同样, 图 15 显示的 addPkg 方法,映射到 HTTP POST 和的 updatePkg 方法,映射到 HTTP 放。
图 15 添加和更新功能
exports.addPkg = function (req, res) {
var pkg = req.body;
console.log('Adding pkgs: ' + JSON.stringify(pkg));
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
db.collection('pkgs', function (err, collection) {
collection.insert(pkg, { safe: true }, function (err, result) {
if (err) {
res.send({ 'error': 'An error has occurred' });
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
}
})
};
exports.updatePkg = function (req, res) {
var id = req.params.id;
var pkg = req.body;
console.log('Updating pkgs: ' + id);
console.log(JSON.stringify(pkg));
MongoClient.connect(connectionString, function (err, db) {
if (err) throw err;
if (!err) {
db.collection('pkgs', function (err, collection) {
collection.update({ '_id': new BSON.ObjectID(id) },
pkg, { safe: true }, function (err, result) {
if (err) {
console.log('Error updating pkg: ' + err);
res.send({ 'error': 'An error has occurred' });
} else {
console.log('' + result + ' document(s) updated');
res.send(pkg);
}
});
});
}
})
};
如果你按照本文到目前为止,你应该能够实现自己的删除功能。 我会把它留给您作为练习。 保存和首先在本地运行的 Web 站点,然后将它发布到 Azure 的 Web 站点来测试每个其余函数。 为其余 Web 服务和 Web 站点的完整源代码是可在 github.com/dynamicdeploy/appsforazure。
一旦你有了运行的端到端应用程序,您可以扩展你的 MongoDB 基础设施 (或服务) 根据用户负载。 像这篇文章,你不需要任何基础结构部署大规模 Node.js 和 MongoDB Web 站点在 Azure 上。 我附带的源代码中提供的骨架将帮助您开始构建 Web 服务和 Web 站点在 Node.js 中 Azure 网站上。
总结
这篇文章的目的是让你舒适的构建 Web 服务在 Node.js 中的 Azure 网站上。 Node.js 和 MongoDB 相互补充,因为他们都可作为平台即服务 (PaaS),还有没有前期的基础结构成本构建一个完整的 Web 站点和动态缩放它出来。 作为开发人员,您可以专注于建筑和消费权从云变成移动应用程序的 Web 服务。 因此,我相信 Azure 的 Web 站点是 PaaS 做得正确。
Tejaswi Redkar 是一个作者和软件开发商。他目前作为应用程序的平台战略和社区主任为微软工作。他的书,"Windows Azure 的 Web 站点:建设速度快的 Web 应用程序"(动态部署 LLC,2013年),是最全面和最畅销主题。Redkar 也是 appsforazure Windows 应用商店应用程序的创建者和 dynamicdeploy.com,在那里他经历第一手云中运行的生产应用。你可以给他在伸出 tejaswi_redkar@hotmail.com 和跟着他在 Twitter 上 twitter.com/tejaswiredkar。
衷心感谢以下技术专家参与本文的审阅:微软 Azure 产品管理团队