OpenWhisk是与IBM Cloud®集成的基于云的第一个基于事件的分布式编程服务。 OpenWhisk使用无服务器部署和操作模型 ,该模型隐藏了基础架构的复杂性,使您可以专注于要执行的代码。
即使OpenWhisk是为内部处理而设计的,它也为面向用户的应用程序提供了许多好处。 将其与静态文件结合使用时,可以使用它来提供相对易于调试的应用程序。 而且,由于与在PaaS平台上运行服务器进程相比,OpenWhisk应用程序的计算强度要低得多,因此它们的价格也要便宜得多。
使用OpenWhisk的另一个好处是它的模块化体系结构,它使您可以将应用程序实现为微服务的集合。 您可以轻松修改部分用户界面,而无需更改其余部分,或在多个应用程序中重复使用面板。
在本教程中,我们将从编写一个简单的“ Hello OpenWhisk”应用程序开始。 然后,我们将该应用程序扩展到更有用的一本多语言短语书的开头。
构建OpenWhisk应用程序所需的内容
- 一个IBM Cloud帐户(注册您的免费试用帐户,或者如果已经拥有一个帐户,则登录到IBM Cloud )
- HTML和JavaScript的实用知识
- MEAN应用程序堆栈(至少Angular)的工作知识
(如果您不熟悉MEAN,则可以从IBM developerWorks上分三部分的系列教程开始“ 使用IBM Cloud和MEAN stack构建自发布Facebook应用程序 ”。)
一个简单的应用程序:“ Hello OpenWhisk”
要构建面向用户的OpenWhisk应用程序,首先让我们构建一个简单的OpenWhisk微服务,并使其可从Web浏览器使用。 单击此处查看其运行情况。
创建一个简单的OpenWhisk操作
要创建一个OpenWhisk操作:
- 转到IBM Cloud中的OpenWhisk控制台 。
- 登录到IBM Cloud,然后单击开始创建以从浏览器使用OpenWhisk,然后输入编辑器。
- 点击开发左侧边栏。
- 单击创建动作 。
- 使用以下参数创建一个新动作:
领域 值 名称 不重要的 执行执行阶段 Node.js 6 选择一个样品(或空白) 从空白石板开始 - 单击创建动作 。
默认情况下,OpenWhisk操作是JavaScript。 他们在输入中接收到关联数组,并返回另一个作为其输出。 就我们的目的而言,响应将具有两个字段:html
(包含要显示HTML代码)和js
(包含要在浏览器上运行JavaScript代码)。 -
用以下代码替换JavaScript代码:
/** * * main() will be invoked when you Run This Action. * */ function main(params) { var name; name = params.name; if (name == undefined) name = ""; return { html: "<b>" + JSON.stringify(params) + "</b>", js: "alert('hello " + name + "');" }; }
- 单击“运行此操作” 。
- 在输入中添加一个名称字段:
{ "message": "choose a value to pass to My New Action", "name": "Ori" }
- 单击“ 启用它” ,然后使用此值运行 。
- 看到输出包含HTML和JavaScript:
- 单击关闭 。
创建一个OpenWhisk API
为了方便从外部(例如从Web浏览器)访问OpenWhisk操作,我们创建了一个可公开访问的API:
- 点击左侧栏中的API 。
- 单击“ 创建OpenWhisk API” 。
- 使用以下参数创建一个API:
领域 值 API名称 面向用户的应用程序 API的基本路径 / api /用户界面 启用CORS,以便基于浏览器的应用程序可以调用此API 已选 - 点击保存 。 我们可以在此步骤中创建操作,但是我更喜欢解释如何独立地进行操作,因为您需要在本文后面进行操作。
- 单击左侧边栏上的定义 。
- 单击创建操作 。
- 使用以下参数创建一个新操作:
领域 值 路径 /不重要的 动词 得到 包含动作的包裹 默认 行动 不重要的 响应内容类型 应用程序/ json - 点击保存 。 然后,向下滚动并单击保存 。
- 点击左侧栏中的摘要 。
- 单击“路由”下的URL。 它应该失败,并显示以下错误消息:
- 在URL末尾添加
/trivial
。 您应该使用HTML和JavaScript返回JSON结构: - 将“路由”下的URL复制到文本文件。 您很快就会需要它。
浏览器端代码
过去,有必要使用Node.js应用程序作为OpenWhisk的管道。 但是,既然API可以启用CORS(跨域资源共享),那么您所需的就是一个index.html文件,该文件可以来自任何地方。
您需要做的就是从GitHub下载文件,将第21行中owUrl变量的值修改为“ Route”值,然后在浏览器中打开文件。 它将调用琐碎的OpenWhisk操作,在响应中显示HTML,然后运行JavaScript
浏览器端代码使用Angular库 (MEAN堆栈中的“ A”)。 该库带有名为$http
的服务,该服务允许浏览器中JavaScript代码充当Web客户端。
完成大部分工作的函数是$scope.getHtml
。 此函数将操作的名称附加到路由URL并尝试获取它。
$http.get(owUrl + "/" + action)
如果请求成功,则结果将为response.data
,已经被解析(正确地为JSON)。 此代码使用jQuery。 $("# " + tag)
搜索其id属性为tag
HTML tag
。 然后, .html(<string>)
方法将该标签HTML设置为字符串,在本例中为response.data.html
,这是OpenWhisk的结果。 请注意,这通常是冒险的操作。 但是,只要我们确保从OpenWhisk发送HTML是安全的,这里就可以接受。
.then(function(response) {
$("# " + tag).html(response.data.html);
eval
函数在response.data.js
获取JavaScript代码,并执行它。
eval(response.data.js);
一个更有用的应用:词组翻译器
现在,我们正在运行一个简单的“ Hello OpenWhisk”应用程序,让我们将其变成有用的应用程序。 该应用程序允许您选择英语单词,并为您提供多种语言的单词。 为了简单起见,该应用程序的单词列表是硬连接的。 如果要使用数据库,则可以使用与Node.js应用程序相同的方式进行操作。
创建两个面板
在此应用程序中,我们使用两个面板-一个用于导航的侧面板和一个用于显示信息的主面板。 这两个面板在OpenWhisk的panels
动作中指定。 使用Bootstrap框架将它们并排放置。
function main(params) {// Store the HTML to send in this variable
var html = "";
// The two main panels
html = '<div class="col-md-3" id="side"></div>' +
'<div class="col-md-9" id="main"></div>';
// The row-fluid
html = '<div class="row-fluid">' + html + "</div>";
// The container-fluid
html = '<div class="container-fluid">' + html + "</div>";
请注意,这两个面板具有id
属性。 该操作返回JavaScript代码调用getHtml
填充这两个面板。
return {
"html": html,
"js": '$scope.getHtml("side", "sidepanel"); $scope.getHtml("main", "mainpanel");'
};
}
创建动作并将其启用后,将新操作添加到API中,并使用路径/panels
进行调用。
创建侧面板
侧面板将单词列表显示为按钮。 当其中任何一个被按下时,它将使用getHtml
函数将有关该单词的信息填充到主面板中。 这是动作:
function main(params) {
var words = ["Hello", "Goodbye", "Thanks", "You're welcome"];
var html = "";
for (var i=0; i<words.length; i++) {
该代码不在Angular范围内,因此无法调用$scope.getHtml
。 为了解决这个问题,存根创建了一个名为scope
的全局变量,并为其分配了$scope
的值。 该函数本身在Angular范围内,因此可以使用$http
。 单词本身会转义以允许包含撇号的表达式,例如“不客气”。
该查询用作操作的一部分,是将参数传输到主面板操作的简便方法。 它会出现在输入中,如您将在下一部分中看到的那样。
var onClick = "scope.getHtml('main', 'mainpanel?word=" + escape(words[i]) + "')";
html += '<p><button type="button" class="btn btn-info" onClick="'
+ onClick + '">' + words[i] + '</button></p>';
}
返回值不包含JavaScript,因为在显示HTML时不需要运行任何JavaScript。
return { "html": html };
}
将此操作添加为/sidepanel
到API。
创建主面板
主面板显示一个单词和该程序已知的所有翻译。 它使用传递给main
的参数来获取单词,并基于哈希表构建HTML。 同样,它不需要告诉浏览器运行任何JavaScript。
function main(params) {
var words = {
"Hello" : {
Hebrew: "Shalom",
Spanish: "Hola",
Arabic: "Marchaba"
}
// The full list of words is in GitHub
};
var html = "";
// Heading
html += "<h2>" + params.word + "</h2>";
此参数来自侧面板使用的URL的查询部分。
var list = words[params.word];
if (list == undefined)
html += "I am not familiar with this word, sorry";
else {
var langs = Object.keys(list);
html += '<table class="table table-striped">';
for (var i=0; i<langs.length; i++)
html += '<tr><th>' + langs[i] + '</th><td>' + list[langs[i]] + '</td></tr>';
html += "</table>";
}
return { "html": html };
}
将此动作添加为/mainpanel
到API。
修改index.html
最后,更改index.html中的第41行以获得panels
而不是trivial
panels
。
结论
希望这些简单的应用程序使您对OpenWhisk的功能有所了解。 OpenWhisk平台使您可以开发和执行逻辑以响应应用程序中的事件,而不必担心基础架构。
OpenWhisk可作为IBM Cloud服务和GitHub上的开源项目提供,以鼓励开发人员加速其开发并生成事件提供者和使用者的强大生态系统。