取得领先
VMware 提供培训和认证,以加速您的进步。
了解更多Spring 社区的各位,大家好!
Roy Clarkson 和我将在今年的 SpringOne 2014 大会上做一个名为 Spring Data REST - Data Meets Hypermedia 的演讲。我们将探讨如何快速弥合强大的 Spring Data 后端与支持超媒体的 RESTful 前端之间的差距。
在演讲的一部分中,我们将深入研究一个 JavaScript 前端,该前端允许用户拍照并将其上传到网站。该网站会反过来从后端获取图像。仅凭这一点并不难,这要归功于 Spring Data REST 提供的功能齐全的 RESTful API。
但是,直接获取多个图像效率不高,并且容易冻结 Web 浏览器。感谢我们团队中的 CujoJS 成员(Brian Cavalier 和 John Hann),我能够使用最近发布的 when.js 模块并编写更流畅的体验。
以下片段展示了 rest.js 与 when.js 通过 promise 结合使用的核心,以及它如何使编写可读且功能正常的代码变得非常简单。
首先,我们引入一些关键模块
var rest = require('rest');
var when = require('when');
var defaultRequest = require('rest/interceptor/defaultRequest');
var mime = require('rest/interceptor/mime');
var hateoas = require('rest/interceptor/hateoas');
然后,我们使用一个 mime
拦截器、一个 hateoas
拦截器配置一个 api
对象,并将其配置为默认 Accept
标头为 application/hal+json
,以便 Spring Data REST 使用 HAL。
var api = rest
.wrap(mime)
.wrap(hateoas)
.wrap(defaultRequest, {headers: {'Accept': 'application/hal+json'}});
通过该配置,我们可以执行一些 RESTful 调用来获取图像数组,而不会破坏用户的体验
when.all(api({
method: 'GET',
path: gallery._links.items.href,
params: {projection: "noImages"}
}).then(function (response) {
if (response.entity._embedded) {
return response.entity._embedded.items.map(function (itemWithoutImage) {
return api({path: itemWithoutImage._links.self.href})
})
} else {
return [];
}
})).done(function(itemsWithImages) {
itemsWithImages.forEach(function(item) {
items[item._links.self.href] = item.entity;
nestedTable.append(createItemRowForGallery(item.entity, gallery));
})
})
发生了什么?让我们看看每个小块,并探讨发生了什么。
api({
method: 'GET',
path: gallery._links.items.href,
params: {projection: "noImages"}
})
这是调用以检索与此特定相册相关的项目数组。它返回一个 promise,为我们提供了一些不错的选择。
注意:它使用
?projection=noImages
获取不带图像数据的项目 URI 列表。(一次性检索十个 2MB 图像!)
.then(function (response) {
...
})
此函数然后获取 URI 列表,并将获取其单个图像的工作分解。
if (response.entity._embedded) {
return response.entity._embedded.items.map(function (itemWithoutImage) {
return api({path: itemWithoutImage._links.self.href})
})
} else {
return [];
}
在 then
函数内部,代码查找 _embedded
数据,如果存在,则将无图像项目的数组 1 对 1 转换为 GET
promise 的数组,获取每个项目的实际图像。如果没有 _embedded
数据,则返回一个空数组。
when.all(
...
).done(function(itemsWithImages) {
itemsWithImages.forEach(function(item) {
items[item._links.self.href] = item.entity;
nestedTable.append(createItemRowForGallery(item.entity, gallery));
})
})
获取图像数据的 promise 数组用 when.all 包装,这是一个方便的函数,它将等待每个 promise 完成后再继续。
由于我们打算通过在屏幕上显示所有这些 GET
的输出来使用它们,因此我们以 done()
结束。 itemsWithImages
由 when.all
提供,是一个大小相等的数组,其中包含每个 promise 的结果。
顺便说一句:如果您不知道...使用 promise 时的规则 #1 是 then() 函数调用必须返回一个对象(将被包装为 promise)或 promise 本身。如果您打算实际使用结果并完成它,请改用 done()。
如果您是 JavaScript 新手,这可能看起来需要吸收很多东西。但是作为一个 JavaScript 新手,我发现此 API 使我可以轻松地表达我想做的事情。
如果您想了解更多信息,请务必注册 今年 SpringOne 的演讲!我们将研究此照片拍摄应用程序的桌面版本。我们还将深入研究移动友好的浏览器页面和本机移动应用程序,它们都可以让您使用手机的摄像头拍照并上传到该网站。
干杯!