2015 年 11 月

第 30 卷,第 12 期

此文章由机器翻译。

数据点 - Aurelia 与 DocumentDB 结合: 结合之旅

通过 Julie Lerman | 2015 年 11 月

Julie Lerman在过去的几个月您所见,通过本专栏中,我探测到未知的领域。我年 9 月的专栏中深入探讨了名为 Aurelia,与后端 ASP.NET 5 Web API 来检索和存储数据通信 upstart JavaScript 客户端框架中的数据绑定。该 Web API 在后台都使用 SQL Server 和实体框架。我年 6 月的专栏中探讨了新 Microsoft Azure NoSQL 数据库服务,DocumentDB。该列中我还构建了 ASP.NET MVC 5 Web API,但该 Web API 利用 DocumentDB.NET 客户端库与 DocumentDB 数据库通信。

与各个轮子 greased Aurelia 和 DocumentDB,我希望将这两个组合到一起。我讲述的内容向下一些凹凸道路和命中一些墙,但最终最终上正确的路径以允许 Aurelia DocumentDB 与进行通信。在本专栏中,我将分享一些我在此过程中中学到的经验,并简要介绍我最终的解决方案。在即将发布的专栏中,我将提供有关该解决方案的详细信息。

当您将肯定学习大量从我最终总结出了解决方案时,我认为在此过程中时采取的步骤,甚至包括那些导致失败,同样教育。

我将通过共享我的计划开始 — 在使用 JavaScript 和其许多 Api、 工具和模式的缺乏经验的真空产生 — 然后显示内容时看上去很好的方法以实现我的目标。如果我改为返回直接迁移到正确的路径,很有第二个想将仅在同一到达困境我找到更好的方法,我选择和重试已过。然后,当然,我将与您共享真实的路径,尽管它需要进行更多本专栏来告诉整篇文章单个一部分。

优秀的规划: "如何难?"

Azure DocumentDB 是一种服务,并与它的原始交互是通过 SQL 语法或 RESTful HTTP 调用。在以前的专栏中,而不是以该低级别工作我利用了 Microsoft 已为 DocumentDB 创建的许多 Api 之一 —.NET API。这使我可以使用 LINQ 来表示和执行针对我的数据库的查询如:

return Client.CreateDocumentQuery(Collection.DocumentsLink)
       .Where(d => d.Id == id)
       .AsEnumerable()
       .FirstOrDefault();

我编写了一个 Web API 来为我完成这项工作。

在我的专栏 Aurelia 数据绑定演示中,我就能够方便地进行 HTTP 调用到不同的 Web API,一个使用实体框架进行命中 SQL Server 数据库。我可能已经只需替换为该 Web API 是我在此之前构建可以与 DocumentDB 交流。将在该方案中,完成我的工作和此专栏应该会由我曾经阅读过的最短的一个。如何令人乏味。

相反,我认为它在某些情况下将会更加有趣使用 DocumentDB 提供直接的其余部分交互。它看起来非常简单。DocumentDB 文档显示 HTTP 请求对 DocumentDB,我认为我能够可以利用所做的很多的示例。图 1 说明一个示例。

图 1 到 DocumentDB 示例 HTTP 请求

POST https://contosomarketing.documents.azure.com/dbs/XP0mAA==/colls/XP0mAJ3H-AA=/docs HTTP/1.1
x-ms-DocumentDB-isquery: True
x-ms-date: Mon, 18 Apr 2015 13:05:49 GMT
authorization: type%3dmaster%26ver%3d1.0%26sig[A HASH GOES HERE]
x-ms-version: 2015-04-08
Accept: application/json
Content-Type: application/query+json
Host: contosomarketing.documents.azure.com
Content-Length: 50
{
 query: "SELECT * FROM root WHERE (root.Author.id = 'Don')",
 parameters: []
}

但并不那么容易。若要开始,您将看到授权中,主密钥不是您想要在客户端应用程序内提供的内容。此外,它不是真正来源于在 Azure 门户中 ; DocumentDB 设置的主密钥它是对键加的其他信息的哈希值。"访问控制上 DocumentDB 资源"文章网址 bit.ly/1O9dBfP 介绍如何构造此字符串中,但即使这并不让我能够在 Fiddler 中测试这些 API 调用。

但更大的问题是我不会执行此操作在客户端应用程序中,是否仍要。根据"确保安全访问到 DocumentDB 数据"的建议体系结构 (bit.ly/1N2ZiuF) 是创建具有对您的主密钥的安全访问并能够生成并返回要使用的客户端应用程序的资源键的中间件。

因此,我写的。我构建 ASP.NET Web API 使用 DocumentDB.NET 客户端按需返回的正确组合的资源键。这需要执行的所有是我以前的 DocumentDB 专栏,我在其中定义我的 Azure 帐户、 数据库客户端、 该数据库在该客户端以及在该数据库内的集合的一部分的安装程序相同的代码。此外,我必须连接到数据库 ; 一个 85 行控制器选中了某用户 ;检查为清除并重新创建该用户针对我原准备执行 ; 该操作的权限然后生成、 哈希运算并返回给请求客户端的资源令牌。这就是代码的要理解和设置非常复杂的一些。

与该服务后下, 一步是让我 Aurelia 的应用程序调用该服务可以检索给定的操作的令牌然后重用该令牌中该操作。这没有太大区别从长远来看比我们使用,例如,为 Windows Communication Foundation (WCF) 服务的安全操作。但它所做的非常琐碎的解决方案。并在结束时,我仍不能因为没有更多的复杂性所需的 DocumentDB 构造合适的请求与在客户端 (JavaScript) 我生成的资源令牌。DocumentDB 拒绝授权我的请求来检索数据。所以我决定在我自己 RESTful 调用直接从客户端应用程序通过 HTTP 我 DocumentDB 是不要通向成功的路径。我操作,但是,预计的 DocumentDB 发展,因此将用于连接到它,我们选项以及我打算在将来再次访问这一想法。

尽管如此,所有未丢失。DocumentDB 还有 JavaScript SDK。此 SDK 会知道如何构建 RESTful 调用 DocumentDB 到我的名义即使我已使用其较高级别的方法。我进入我理解了我可以让它构造为我使用从我 ResourceTokenGenerator 的 Web API 请求的资源令牌请求的客户端解决方案的 SDK。最后,这感觉像的正确路径,但最后我按另一种墙上: 无法启用跨域资源共享 (CORS),这意味着不会允许我在一个域上的客户端应用程序从我的服务在另一台到调用。

此时,我的资源和我的好奇心有关将具有已用完 RESTful 调用没有为此对我来说,一个包装的情况下,并仍不想要只需转到我现有的 Web API 来获取我 Aurelia 的应用程序可以与 DocumentDB 交流,我讲述的内容关闭另一个的道路。

成功: DocumentDB、 Express、 Aurelia 和 Node.js

除了。NET 和 JavaScript 客户端 Sdk,DocumentDB 还提供了 Node.js SDK (bit.ly/1LifOa1)。这使您可以使用 Node.js,可在服务器端运行的 JavaScript 实现 — 非常像 ASP.NET 代码隐藏逻辑 — 可以轻松地访问 DocumentDB。所有配置、 身份验证和构建 RESTful API 调用的硬部分包装到方法的 sdk。因此我决定这是我必须为让应用程序与 DocumentDB 我 Aurelia 要遵循的路径。它对我来说意味着大量的新学习障碍。我有永远不会接触 Node.js,是著名的 JavaScript 门外汉;此外,它涉及的其他 API Express,它的核心功能,以使其更轻松地使用 Node.js 的一组包装。但 IntelliTrace 的功能并非仅限于此。对于我第一 Aurelia 深入,我必须要想习惯使用命令行中的使用以及使用 SublimeText,是为 Web 开发更 savvier 比记事本的文本编辑器。由于大部分该早期应用程序中的操作是在客户端,我就能够调试的浏览器。但现在我已在其中调试位于服务器上的 Node.js 代码。打开 Visual Studio 系列产品,Visual Studio 代码,为添加的新内容是很棒的工具程序。

幸运的是,我就能够受益于两个密钥的示例。DocumentDB 一端是用于构建与 Node.js 和 DocumentDB 一个小型 Web 应用程序的演练 (bit.ly/1FljQs6)。在 Aurelia 一侧,没有一个存储库设置的主干 Aurelia 应用程序使用已集成的 Node.js 服务器端逻辑的 GitHub 上 (bit.ly/1XkMuEX)。

为了实现我的解决方案,非常重要有充分的了解使用 Node.js SDK 示例的基础结构。我将花费超出高级预排中提供了哪些功能的详细信息公开此专栏的其余部分。这将为如何我关联了 API 在我最终解决方案中的显示设置您权限。

DocumentDB Node.js 预排中提供了利用 DocumentDB Node.js SDK 进行通信与 DocumentDB 的 Node.js 中的后端逻辑。此逻辑的第一段是负责创建实例的数据库连接,如有必要,首先创建数据库并创建要使用的数据库中的特定集合的实例的一对的泛型的实用程序。这些实用程序可以重用在其他应用程序进行通信与任何 DocumentDB 因为 DocumentDB 允许您传入的身份验证信息和其他信息以指定的数据库和正在使用的集合。

此实用程序类开始通过使对用于已安装到解决方案的 Node.js DocumentDB SDK 的引用:

var DocumentDBClient = require('DocumentDB').DocumentClient;

它然后设置作为参数的相关的连接信息所采用的方法。在这里,例如,是 getOrCreateDatabase 方法,该首先定义一个查询来获取该数据库从 Azure,然后使用 SDK DocumentClient 类的 queryDatabases 方法来执行该查询方法的类声明的开头。如果结果都为空,(未显示) 的另一次调用将为您创建数据库。从方法返回的数据库实例。您可以看到所引用的文章中的 DocDBUtils 类的完整清单 (bit.ly/1FljQs6):

var DocDBUtils = {
 getOrCreateDatabase: function (client, databaseId, callback) {
  var querySpec = {
   query: 'SELECT * FROM root r WHERE r.id=@id',
   parameters: [{
    name: '@id',
    value: databaseId
   }]
  };
  client.queryDatabases(querySpec).toArray(function (err, results) {
  // Additional logic to specify callbacks and more

逻辑,在一个名为 tasklist.js,文件中的第二个块区是类似于一个控制器。它提供了利用 DocDBUtils 类使您可以与数据进行交互所提供的数据库和集合实例的方法。此控制器专为存储和检索 ToDo 项的示例设计 — 任务。任务对象封装在一个名为 TaskDao,类,您将看到对控制器类中的 TaskDao 实例的引用。控制器具有用于的方法来检索任务,以及若要添加新的和更新和删除。此类开头是对 DocumentDB SDK,以及我刚刚介绍的实用程序类的引用:

var DocumentDBClient = require('DocumentDB').DocumentClient;
var docdbUtils = require('./docdbUtils');

Tasklist.js 包括 showTasks 和 addTask 之类的函数。这些函数通过请求对象,并允许以将请求从浏览器一起传递到另一个进程或注入随意的响应,将获取传递回浏览器的 Node.js 的响应对象作为参数执行遵循 Node.js 约定。图 2 会显示 showTasks 函数。

图 2 showTasks 命令 tasklist.js 控制器类中

showTasks: function (request, response) {
 var self = this;
 var querySpec = {
  query: 'SELECT * FROM root r WHERE r.completed=@completed',
  parameters: [{
   name: '@completed',
   value: false
  }]
 };
 self.taskDao.find(querySpec, function (err, items) {
  if (err) {
   throw (err);
  }
  response.render('index', {
   title: 'My ToDo List ',
   tasks: items
  });
 });
},

请记住没有一个其他库 — Express — 在此示例中使用。速成版将 Node.js 功能包装到更高级别的方法。请注意 showTasks 函数使用快速呈现要呈现索引视图 (如 index.html),并传递从 DocumentDB 到可用于在 Index.html 文件中使用的任务属性中检索到的项的响应对象的方法。

它可响应对 Web 站点的路由,控制器 (TaskList 类) 将是服务器端 Node.js 逻辑的第一个入口点。中的控制器方法的逻辑使用 taskDAO 对象触发查询和更新通过调用 self.taskDao.find showTasks 函数中所示。taskDAO 具有 DocDbUtils 用于设置数据库和集合要使用 init 函数。与现有参与,它可以 DocumentDB SDK 直接使用定义和执行查询和更新在其查找、 getitem 和 updateItem 函数中,作为 图 3 显示。

工作流的 DocumentDb Node.js 示例应用程序类和 SDK 的依赖关系
图 3 工作流依赖关系的 DocumentDb Node.js 示例应用程序类和 SDK

与在 Node.js 中设置的后端逻辑下, 一步是构建的前端。预排中的 DocumentDB 站点上使用一个称为 Jade 的视图生成框架。与为视图和使用 Jade API 的路由设置的 HTML 文件,用户界面是能够通过在服务器上,存储在哪里可以安全地我 DocumentDB 的密钥进行授权我与数据交互的 taskList 控制器调用来响应用户导航请求。

后续步骤: 挂接到 Node.js 后端 Aurelia

但请记住,我的目标是要 Aurelia 用作客户端框架中,不 Jade。什么下一步有意有关使用 DocumentDB Node.js SDK 并将它们应用到已启用 Node.js 的主干应用程序 Aurelia 节点示例在 GitHub 上提供的课程。Aurelia 路由但是,工作以不同方式从 Jade 路由位并且它不是只需"单击"这两个填数游戏部分在一起。与 Node.js 和速成版,我"知道的足够-到-将-危险"的常规 javascript 编程技巧以及我缺乏经验进行面临的挑战不需要它要大得多。但是我未最终处理它万能的数目 Aurelia 核心团队成员的帮助。

在我的下一篇专栏中我将向您介绍关键的连接器的控制器和 Aurelia 路由之间并显示如何使用服务器端 Node.js 解决方案与我 DocumentDB 交互相比的直接从 Aurelia 到 Web API 的 HTTP 调用的简单性。


Julie Lerman 是 Microsoft MVP、.NET 导师和顾问,住在佛蒙特州的山区。您可以在全球的用户组和会议中看到她对数据访问和其他 .NET 主题的演示。她是《Programming Entity Framework》(2010) 以及“代码优先”版 (2011) 和 DbContext 版 (2012)(均出自 O’Reilly Media)的作者,博客网址为 thedatafarm.com/blog。请关注她的 Twitter: @julielerman 并查看其 Pluralsight 课程,网址 juliel.me /ps-videos

衷心感谢以下技术专家参与本文的审阅: Ryan CrawCour 和 Patrick Walters
Ryan CrawCour 是一名具有 20 年数据库经验的老将,他在很多年以前就开始编写首个适用于 SQL Server 4.2 的存储过程。后来经过诸多光标、连接和存储过程,他开始探索令人兴奋的 NoSQL 解决方案的自由世界。

Patrick Walters 已经很好的 Aurelia 开发人员社区人员喜欢产品 ear 官方 Aurelia gitter 通道中有关的问题的一员。