在许多云服务中,云对象存储的成长或许是最快的。云对象存储常被用于存储照片、图像、文档和音视频文件。每一天,人们都会发现其最喜欢的对象存储的新用途。无论您开发的应用程序有何用途,理解云对象存储服务都是构建真实的可扩展解决方案的一个重要步骤。
“ 有了这里学到的知识,您就可以利用 IBM Object Storage 非常快地开发优秀的应用程序。 ”
在本教程中,我们将展示如何使用 Bluemix 的 Object Storage 服务(一个基于 OpenStack Swift 的对象存储服务)开发一个简单应用程序,还将解释如何使用 REST 风格的存储 API。您开发的应用程序允许用户利用 Bluemix 的 Object Storage 服务上传、下载和管理其照片和文档。您还可以下载示例应用程序并查看代码。有了这里学到的知识,您就可以使用 Object Storage 服务快速开发优秀的应用程序。
获取代码
awesome-store.mybluemix.net
。这个 URL 是应用程序名称和您选择的域的组合。您可以使用该 URL 从任何浏览器访问您的应用程序。 点击查看大图
关闭 [x]
VCAP_SERVICES
。这是一部分重要的信息,您的应用程序需要使用它们来调用 Object Storage 服务,比如用于为应用程序用户创建一个帐户,允许用户上传和下载文档。下图提供了一个示例。 username
和 password
显得杂乱无章,以增加安全性。 点击查看大图
关闭 [x]
您可以注意到,在 credentials 部分,可以找到 auth_uri
、 username
和 password
。这 3 个字段用于向服务验证您的应用程序,它们现在开始被称为 auth_uri、username
和 password
。您一定要知道的是,这个成对出现的 username
和 password
是您的应用程序用于向服务执行验证的凭据。如果您的应用程序支持多个用户,那么它们与您应用程序的 username
和 password
不同。
点击查看大图
关闭 [x]
因为本教程的目的是演示如何使用 Object Storage 服务,所以我们不会深入详细介绍 Node.js 应用程序编程。相反,我们将重点介绍编写 Object Storage 服务需要注意的 3 个重要方面。
/gettoken/:userid
变成 /gettoken/tongli
。 /gettoken/:userid
:获取 userid
的一个访问令牌 /listfolders/:userid
:列出 userid
的所有文件夹。 /createfolder/:userid/:foldername
:为 userid
创建一个名为 foldername
的文件夹。 /delfolder/:userid/:foldername
:删除 userid 的一个文件夹。这个文件夹未在应用程序中实现,作为练习,您可以添加该实现。该实现非常类似于 deldoc
操作。 /listdocs/:userid/:foldername
:列出 userid 的一个文件夹的所有文档。 /createdoc/:userid/:foldername/:docname
:在 foldername
文件夹下为 userid 创建一个名为 docname
的文档。您可能注意到,GET 请求没有真正发送文档的任何内容。在此应用程序中,只发送了一个硬编码的字符串。 /getdoc/:userid/:foldername/:docname
:在 userid
下的 foldername
文件夹中获取名为 docname
的文档。 /deldoc/:userid/:foldername/:docname
:删除一个文档。 doctype html html include head body table(style="width:100%") tr td(style= "width:307px" ) img(src="/images/newapp-icon.png") td block content
extends layout block content div(id="results") h2 pre !=JSON.stringify(body, null, 2)
var services
行的后面: The existing code: var services = JSON.parse(process.env.VCAP_SERVICES || "{}"); The new code to be added after the above line: app.get('/gettoken/:userid', function(req, res){ res.render('results', {body: {}); });
新代码使用 results.jade
作为模板,将一个名为 body
的变量传递给该模板,然后呈现 HTML。
app.js
中的更改使我们能实现更多功能。尽管我们目前尚未完成多少更改,但仍可部署此应用程序来查看新代码的运行情况。使用 cf push
命令将应用程序部署在 Bluemix 上,然后在浏览器中打开 http://awesome-store.mybluemix.net/gettoken/tong 来查看结果,结果类似于下图: 如果看到错误,请仔细检查这两个文件和 app.js
文件中执行的更改。通常浏览器会显示有帮助的调试信息。
auth_uri/<app_userid>
。在此示例中,URL 类似于: 点击查看代码清单
关闭 [x]
https://swift.ng.bluemix.net/auth/e40bf8f2-c3c6-4e51-8cde-476e30574637/fe07a633-61b3-4797-9a4d-c36daee7335b/tong
请注意,URL 并不是您从 VCAP_SERVICES
变量获取的完全相同的 auth_uri
。它是 auth_uri
与您的应用程序选择的 userid 的串联结果。您的应用程序可以支持多个用户,而且您可以选择任何内容作为 userid,只要这些 userid 在整个应用程序中是惟一的。每个 userid 应惟一地标识您应用程序中的一个用户。基本验证标头应该符合标准的基本验证协议。
The existing code: var express = require('express'); The new code to be added after the above line: var request = require('request');
将以下代码添加到 app.js 文件中,替换掉 3.7 步中添加的行。
var cache = {}; var auth = null; var set_app_vars = function() { var credentials = services['objectstorage'][0]['credentials']; auth = {"auth_uri": credentials['auth_uri'], "userid" : credentials['username'], "password" : credentials['password'], }; auth["secret"] = "Basic " + Buffer(auth.userid + ":" + auth.password).toString("base64"); }; app.get('/gettoken/:userid', function(req, res){ if (!auth) { set_app_vars(); } var res_handler = function(error, response, res_body) { var body = {}; if (!error && response.statusCode == 200) { body = {"userid": req.params.userid, "token": response.headers['x-auth-token'], "url": response.headers['x-storage-url']}; cache[req.params.userid] = body; } else { body = {"token": error, "url": ""}; }; res.render('results', {"body": body}); }; var req_options = { url: auth.auth_uri + '/' + req.params.userid, headers: {'accept': 'application/json', 'Authorization': auth.secret}, timeout: 100000, method: 'GET' }; request(req_options, res_handler); });
在上面的代码中,函数 set_app_vars
接受来自变量 VCAP_SERVICES
的值,并查找该服务实例的 objectstorage
设置。该函数还会获取 auth_uri、userid
和 password
,然后根据基本验证协议创建一个 base64
字符串,并保存它供以后使用。
app.get('/gettoken/:userid')
调用将会设置一个请求处理函数,以便通过这个代码块处理所有针对 /gettoken/:userid
的 GET 请求。在这个代码块中,定义一个响应处理函数和请求选项,以获取 IBM Bluemix Object Storage 所提供的端点的访问令牌。在发送该请求后,响应处理函数会检查响应状态代码,然后创建一个 body
变量并传递它,以便依据 results.jade
文件中提供的定义将其呈现为 HTML 页面。
另请注意,收到的令牌由这个应用程序临时缓存,供以后使用。如果正在使用此服务开发一个真实应用程序,则应缓存该令牌,这样您就无需每次都向此服务发送请求来获取访问令牌。
cf push
命令重新部署应用程序。 http://awesome-store.mybluemix.net/gettoken/tong
tong
的访问令牌。现在是时候为 tong
创建一个文件夹OpenStack Swift 定义来创建文件夹的 API 是一个 PUT 请求,请求标头包含访问令牌。该端点是存储服务的 URL,您会在获取访问令牌时获得它。因此,要创建一个文件夹,可使用上面收到的访问令牌和存储 URL 来发送 PUT 请求。 app.get('/createfolder/:userid/:foldername', function(req, res){ var user_info = cache[req.params.userid]; var res_handler = function(error, response, body) { if (!error && (response.statusCode == 201 || response.statusCode == 204)) { res.render('results', {'body': {result: 'Succeeded!'}}); } else { res.render('results', {'body': {result: 'Failed!'}}); } }; var req_options = { url: user_info['url'] + "/" + req.params.foldername, headers: {'accept': 'application/json', 'X-Auth-Token': user_info['token']}, timeout: 100000, method: 'PUT' }; request(req_options, res_handler); });
/createfolder/:userid/:foldername
的请求定义了一个处理函数。在您自己的应用程序中,您能够以任何您喜欢的方式定义该 URL,但您应采用某种方式来获取文件夹名称和 userid。例如,您可以对 userid 使用会话跟踪。或者可以使用一个 form post 来获取文件夹名称。有许多选项可供选择。在此应用程序中,在请求路径中使用了一个参数。在收到请求后,它会在缓存中找到用户信息,定义响应处理函数和请求选项,然后发送请求。 /gettoken/:userid
请求再次获取该令牌。以下是两个可以试用的 URL。 在前面的步骤中,您成功添加了用来获取访问令牌和创建文件夹的函数。在这一节中,我们将添加另外一些代码,以便将文档上传到已创建的名为 newfolder 的文件夹。OpenStack Swift 上传对象 API 也是端点上的一个 PUT 请求,该请求包含存储 URL 和文件夹名称。访问令牌必须包含在请求标头中。
以下是上传文档的代码:
app.get('/createdoc/:userid/:foldername/:docname', function(req, res){ var user_info = cache[req.params.userid]; var res_handler = function(error, response, body) { if (!error && response.statusCode == 201) { res.render('results', {'body': {result: 'Succeeded!'}}); } else { res.render('results', {'body': {result: 'Failed!'}}); } }; var req_options = { url: user_info['url'] + "/" + req.params.foldername + "/" + req.params.docname, headers: {'accept': 'application/json', 'X-Auth-Token': user_info['token']}, timeout: 100000, body: "Some random data", method: 'PUT' }; request(req_options, res_handler); });
上面的代码采用了与前面的代码块相同的模式。它首先在请求 URL 中获取 userid 的访问令牌,然后定义一个响应处理函数和请求选项,最后发送请求。惟一的区别是,我们添加了一个字符串 "Some random data"
作为已上传对象的内容。
在您的应用程序中,您可以为用户提供各种各样的上传文档的途径。因为这在本教程讨论的范畴内,所以我们为文档内容硬编码了示例数据。这使得代码非常简单,而且便于演示,但是,如果按原样使用该应用程序,每个文档都将包含相同的内容。
在本教程中,我们演示了如何创建一个简单的 Node.js 应用程序来使用 Bluemix 的 Object Storage 服务。该应用程序展示了如何获取用户的访问令牌,创建文件夹和上传文档。在应用程序代码中,您还可以发现处理一些请求的代码块,比如列出用户的文件夹,列出文件夹中的文档,删除文档和其他请求。利用您在本教程中学到的知识,快速而又轻松地使用 Object Storage 开发优秀的应用程序。
BLUEMIX SERVICE USED IN THIS TUTORIAL: Object Storage 服务 拥有对配置独立对象存储的内置支持,而且它为每个对象存储创建单独的子帐户。
相关主题: Node.js