{"id":39167,"date":"2016-03-30T22:20:32","date_gmt":"2016-03-30T19:20:32","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=39167"},"modified":"2019-06-08T04:44:44","modified_gmt":"2019-06-08T01:44:44","slug":"ibm-bluemix-openwhisk-101-developing-a-microservice","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/","title":{"rendered":"IBM Bluemix OpenWhisk 101: Developing a Microservice"},"content":{"rendered":"<p><a href=\"https:\/\/www.ibm.com\/cloud\/openwhisk\" target=\"_blank\" rel=\"noopener noreferrer\">IBM Bluemix OpenWhisk<\/a> is an event-driven compute platform that enables developers to build chains of scalable microservices. It executes application logic in response to events or through direct invocations.<\/p>\n<p><a href=\"https:\/\/www.altoros.com\/blog\/introduction-to-ibm-bluemix-openwhisk\/\">Earlier<\/a>, we provided an overview of OpenWhisk&#8217;s architecture and components. This post shows how to develop a simple JavaScript application and deploy it to OpenWhisk. You will also learn about Docker integration.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#Before_we_start\" >Before we start<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#A_%E2%80%9CGoodbye_sir%E2%80%9D_app\" >A &#8220;Goodbye, sir!&#8221; app<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#Docker_included\" >Docker included<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#Conclusion\" >Conclusion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#Further_reading\" >Further reading:<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"Before_we_start\"><\/span>Before we start<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>If you want to follow my code examples, you need to set up a couple of things first:<\/p>\n<ul>\n<li><a href=\"https:\/\/cloud.ibm.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">IBM Bluemix<\/a> account<\/li>\n<li>OpenWhisk <a href=\"https:\/\/cloud.ibm.com\/openwhisk\/\" target=\"_blank\" rel=\"noopener noreferrer\">early access<\/a><\/li>\n<li>Python and <a href=\"https:\/\/pip.pypa.io\/en\/stable\/installing\/\" target=\"_blank\" rel=\"noopener noreferrer\"><code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">pip<\/code><\/a><\/li>\n<li><a href=\"https:\/\/cloud.ibm.com\/functions\/cli\" target=\"_blank\" rel=\"noopener noreferrer\">OpenWhisk CLI<\/a><\/li>\n<\/ul>\n<p>Because OpenWhisk was only recently announced, it is not publicly available yet. It took a couple of hours for my early access to be approved.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"A_%E2%80%9CGoodbye_sir%E2%80%9D_app\"><\/span>A &#8220;Goodbye, sir!&#8221; app<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Below I show how to write some code and actually run it. While the whole world likes to greet each other using boring \u201cHello, World\u201d stuff, we are going to do the opposite. A serious application doesn\u2019t have time for such things, so it\u2019s going to state that it\u2019s busy and politely excuse itself.<\/p>\n<p>The source code can be found on <a href=\"https:\/\/github.com\/Altoros\/getting-started-with-openwhisk\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub<\/a>.<\/p>\n<p>I\u2019m going to use JavaScript here, but you can also work with <a href=\"https:\/\/cloud.ibm.com\/docs\/openwhisk\/openwhisk_about.html\" target=\"_blank\" rel=\"noopener noreferrer\">Swift<\/a>. To start, create the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goodbye-sir<\/code> folder with <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goodbye-sir.js<\/code>:<\/p>\n<pre style=\"padding-left: 30px;\">function main() {\r\n  return { payload: \"I am pretty busy and can't talk right now. Goodbye, sir!\" };\r\n}<\/pre>\n<p><\/p>\n<p>The only interesting part of this function is that it returns a JSON object with the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">payload<\/code> key. Once we send this function into the OpenWhisk service, it will become one of the remotely executable actions. As it turns out, OpenWhisk actions are required to return valid JSON. An important thing to note is that OpenWhisk expects every action to be defined in a single file. The file can contain several functions, but at least one of them should be named <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">main<\/code>.<\/p>\n<p>Now, we need to use the OpenWhisk CLI to actually deploy our code. In terms of OpenWhisk, the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">main<\/code> function will become an action. I like to automate stuff, so let\u2019s write our deployment code into a separate script\u2014<code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">deploy.sh<\/code>:<\/p>\n<pre style=\"padding-left: 30px;\">#!\/bin\/bash\r\n\r\nwsk action update goodbye-sir goodbye-sir.js<\/pre>\n<p><\/p>\n<p>Note that <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">wsk action update<\/code> creates a new action called <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goodbye-sir<\/code> if it is missing. Subsequent calls upload updated code.<\/p>\n<p>And finally, let\u2019s make the script executable and kick off the whole process:<\/p>\n<pre style=\"padding-left: 30px;\">$ chmod +x deploy.sh\r\n$ .\/deploy.sh\r\n# => ok: updated action goodbye-sir<\/pre>\n<p><\/p>\n<p>If you see something like this, you probably haven\u2019t set up the OpenWhisk credentials:<\/p>\n<pre style=\"padding-left: 30px;\">$ .\/deploy.sh\r\n# => usage: wsk action update [-h] -u AUTH [--docker] [--copy] [--sequence]\r\n# =>                         [--lib LIB] [--shared [{yes,no}]]\r\n# =>                         [-a ANNOTATION ANNOTATION] [-p PARAM PARAM]\r\n# =>                         [-t TIMEOUT] [-m MEMORY]\r\n# =>                         name [artifact]\r\n# => wsk action update: error: argument -u\/--auth is required<\/pre>\n<p><\/p>\n<p>Another common issue is that a fresh Bluemix account doesn\u2019t have any application spaces in the default organization. The error looks similar to this:<\/p>\n<pre style=\"padding-left: 30px;\">$ .\/deploy.sh\r\n# => error: The supplied authentication is not authorized to access this resource \r\n# => (code 323536)<\/pre>\n<p><\/p>\n<p>In this case, follow <a href=\"https:\/\/new-console.ng.bluemix.net\/?direct=classic\/#\/manage\/type=org&#038;tabId=users\" target=\"_blank\" rel=\"noopener noreferrer\">the link<\/a> and create a new space. Then, you can copy the OpenWhisk CLI configuration code from <a href=\"https:\/\/cloud.ibm.com\/functions\/cli\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>. Note that it should have the name of your new space at the end of the command.<\/p>\n<p>Now, we invoke our code with the OpenWhisk CLI:<\/p>\n<pre style=\"padding-left: 30px;\">$ wsk action invoke --blocking goodbye-sir\r\n# => ok: invoked goodbye-sir with id abfcdb37efe94b1a8f1807e76385027d\r\n# => response:\r\n# => {\r\n# =>     \"result\": {\r\n# =>         \"payload\": \"I am pretty busy and can't talk right now. Goodbye, sir!\"\r\n# =>     },\r\n# =>     \"status\": \"success\",\r\n# =>     \"success\": true\r\n# => }<\/pre>\n<p><\/p>\n<p>As you might have noticed, we\u2019ve specified the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">--blocking<\/code> parameter. You can call OpenWhisk code asynchronously by simply omitting it. The next command will query OpenWhisk for the action result.<\/p>\n<pre style=\"padding-left: 30px;\">$ wsk action invoke goodbye-sir\r\n# => ok: invoked goodbye-sir with id 6cf984e1fbb74f69a54f07eec508f5e3\r\n\r\n$ wsk activation result 6cf984e1fbb74f69a54f07eec508f5e3\r\n# => {\r\n# =>   \"payload\": \"I am pretty busy and can't talk right now. Goodbye, sir!\"\r\n# => }<\/pre>\n<p><\/p>\n<p>You can also parametrize your actions. Edit <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goodbye-sir.js<\/code>:<\/p>\n<pre style=\"padding-left: 30px;\">function main(params) {\r\n  var name = params.name || \"sir\";\r\n  return {\r\n    payload: \"I am pretty busy and can't talk right now. Goodbye, \" + name + \"!\"\r\n  };\r\n}<\/pre>\n<p><\/p>\n<p>When you deploy and run the code, you should see something similar to:<\/p>\n<pre style=\"padding-left: 30px;\">$ .\/deploy.sh\r\n# => ok: updated action goodbye-sir\r\n\r\n$ wsk action invoke --blocking goodbye-sir --param name Alex\r\n# => ok: invoked goodbye-sir with id 831a1fea3ac74ea4a06a1d05e5dd9822\r\n# => response:\r\n# => {\r\n# =>     \"result\": {\r\n# =>         \"payload\": \"I am pretty busy and can't talk right now. Goodbye, Alex!\"\r\n# =>     },\r\n# =>     \"status\": \"success\",\r\n# =>     \"success\": true\r\n# => }<\/pre>\n<p><\/p>\n<p>And this basically wraps up our \u201cGoodbye, sir!\u201d application.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Docker_included\"><\/span>Docker included<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Let me show you a neat trick.<\/p>\n<pre style=\"padding-left: 30px;\">$ wsk action create --docker example hello-world\r\n# => ok: created action example\r\n\r\n$ wsk action invoke --blocking --result example\r\n# => error: {\r\n# =>    \u2026\r\n# =>     \"logs\": [\r\n# =>        \"2016-03-05T13:48:39.220147731Z stdout: \",\r\n# =>        \"2016-03-05T13:48:39.220213883Z stdout: Hello from Docker.\",\r\n# =>        \"2016-03-05T13:48:39.220227211Z stdout: This message shows that your\r\n# =>        Docker installation appears to be working correctly.\",\r\n# =>        \u2026\r\n# =>    ],\r\n# =>    \u2026\r\n# =>    \"response\": {\r\n# =>        \"result\": {\r\n# =>            \"error\": \"the action did not produce a valid JSON response\"\r\n# =>        },\r\n# =>        \"status\": \"action developer error\",\r\n# =>        \"success\": false\r\n# =>    },\r\n# =>    \u2026\r\n# => }<\/pre>\n<p><\/p>\n<p>As you\u2019ve probably guessed by now, OpenWhisk can run arbitrary Docker images. Currently, <a href=\"https:\/\/new-console.ng.bluemix.net\/docs\/openwhisk\/openwhisk_actions.html#openwhisk_actions_docker\" target=\"_blank\" rel=\"noopener noreferrer\">support<\/a> is limited to publicly available images from the Docker Hub.<\/p>\n<p><center><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk-docker-actions.png\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk-docker-actions.png\" alt=\"ibm-bluemix-openwhisk-docker-actions\" width=\"640\" class=\"aligncenter size-full wp-image-39169\" \/><\/a><\/center><\/p>\n<p>Note that the execution failed because \u201cthe action did not produce a valid JSON response.\u201d Why? OpenWhisk uses <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">STDIN<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">STDOUT<\/code> to talk to the running container. All incoming parameters come into <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">STDIN<\/code> as a string representation of a JSON object. The same is true for <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">STDOUT<\/code>\u2014OpenWhisk expects correct JSON to be printed out as the result of an operation.<\/p>\n<p>Anyway, it\u2019s great to see that Docker actions are available. Developers can work with any language or framework they like and still benefit from using OpenWhisk.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>OpenWhisk is fairly easy to use. In this post, we have seen how to utilize it to run isolated blocks of code. Note that OpenWhisk does not set any limitations on runtimes, so developers can start building language-agnostic microservices right away.<\/p>\n<p>On the downside, there is an issue with performance. Although OpenWhisk is still experimental, I can\u2019t help but notice how slow Docker actions are. It takes about 10 seconds to execute a \u201cHello, World\u201d container.<\/p>\n<p><center><a href=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk-performance.png\"><img decoding=\"async\" src=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk-performance.png\" alt=\"ibm-bluemix-openwhisk-performance\" width=\"640\" class=\"aligncenter size-full wp-image-39170\" \/><\/a><\/center><\/p>\n<p>At the same time, it is not true for JavaScript and Swift actions that work much more quickly.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Further_reading\"><\/span>Further reading:<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/introduction-to-ibm-bluemix-openwhisk\/\">Introduction to IBM Bluemix OpenWhisk<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/how-to-use-openwhisk-docker-actions-in-ibm-bluemix\/\">How to Use OpenWhisk Docker Actions in IBM Bluemix<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<hr \/>\n<p><center><small>The tutorial is written by Alexander Sologub, edited and published by <a href=\"https:\/\/www.altoros.com\/blog\/author\/viktoryia-fedzkovich\/\">Victoria Fedzkovich<\/a> and <a href=\"https:\/\/www.altoros.com\/blog\/author\/alex\/\">Alex Khizhniak<\/a>.<\/small><\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>IBM Bluemix OpenWhisk is an event-driven compute platform that enables developers to build chains of scalable microservices. It executes application logic in response to events or through direct invocations.<\/p>\n<p>Earlier, we provided an overview of OpenWhisk&#8217;s architecture and components. This post shows how to develop a simple JavaScript application and deploy [&#8230;]<\/p>\n","protected":false},"author":42,"featured_media":39168,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[214],"tags":[873,187,146,750],"class_list":["post-39167","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-cloud-native","tag-ibm-bluemix","tag-microservices","tag-openwhisk"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>IBM Bluemix OpenWhisk 101: Developing a Microservice | Altoros<\/title>\n<meta name=\"description\" content=\"Learn how to develop a simple JavaScript application, deploy it to the platform, and run Docker actions.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"IBM Bluemix OpenWhisk 101: Developing a Microservice | Altoros\" \/>\n<meta property=\"og:description\" content=\"IBM Bluemix OpenWhisk is an event-driven compute platform that enables developers to build chains of scalable microservices. It executes application logic in response to events or through direct invocations. Earlier, we provided an overview of OpenWhisk&#8217;s architecture and components. This post shows how to develop a simple JavaScript application and deploy [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2016-03-30T19:20:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-06-08T01:44:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1618\" \/>\n\t<meta property=\"og:image:height\" content=\"860\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Alexander Sologub\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alexander Sologub\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/\",\"name\":\"IBM Bluemix OpenWhisk 101: Developing a Microservice | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png\",\"datePublished\":\"2016-03-30T19:20:32+00:00\",\"dateModified\":\"2019-06-08T01:44:44+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/926ba6b8608065bae61d79cfd7da9bce\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png\",\"width\":1618,\"height\":860},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"IBM Bluemix OpenWhisk 101: Developing a Microservice\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\",\"url\":\"https:\/\/www.altoros.com\/blog\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.altoros.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/926ba6b8608065bae61d79cfd7da9bce\",\"name\":\"Alexander Sologub\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Sologub_Aleksandr.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Sologub_Aleksandr.jpg\",\"caption\":\"Alexander Sologub\"},\"description\":\"Alexander Sologub has 6+ years in software engineering, being an expert in cloud automation and designing architectures for complex cloud-based systems. With strong background in Ruby, Go, and JavaScript, Alex took part in integrating a number of popular clouds with RightScale (a web-based platform for managing cloud infrastructures from multiple providers). His interests embrace building IoT solutions powered by cloud technologies and designing architectures that meet customer needs. Check out Alexander\u2019s profile on GitHub.\",\"url\":\"https:\/\/www.altoros.com\/blog\/author\/alexander-sologub\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"IBM Bluemix OpenWhisk 101: Developing a Microservice | Altoros","description":"Learn how to develop a simple JavaScript application, deploy it to the platform, and run Docker actions.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/","og_locale":"en_US","og_type":"article","og_title":"IBM Bluemix OpenWhisk 101: Developing a Microservice | Altoros","og_description":"IBM Bluemix OpenWhisk is an event-driven compute platform that enables developers to build chains of scalable microservices. It executes application logic in response to events or through direct invocations. Earlier, we provided an overview of OpenWhisk&#8217;s architecture and components. This post shows how to develop a simple JavaScript application and deploy [...]","og_url":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/","og_site_name":"Altoros","article_published_time":"2016-03-30T19:20:32+00:00","article_modified_time":"2019-06-08T01:44:44+00:00","og_image":[{"width":1618,"height":860,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png","type":"image\/png"}],"author":"Alexander Sologub","twitter_misc":{"Written by":"Alexander Sologub","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/","url":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/","name":"IBM Bluemix OpenWhisk 101: Developing a Microservice | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png","datePublished":"2016-03-30T19:20:32+00:00","dateModified":"2019-06-08T01:44:44+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/926ba6b8608065bae61d79cfd7da9bce"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2018\/11\/ibm-bluemix-openwhisk.png","width":1618,"height":860},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/ibm-bluemix-openwhisk-101-developing-a-microservice\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"IBM Bluemix OpenWhisk 101: Developing a Microservice"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/926ba6b8608065bae61d79cfd7da9bce","name":"Alexander Sologub","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Sologub_Aleksandr.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/12\/Sologub_Aleksandr.jpg","caption":"Alexander Sologub"},"description":"Alexander Sologub has 6+ years in software engineering, being an expert in cloud automation and designing architectures for complex cloud-based systems. With strong background in Ruby, Go, and JavaScript, Alex took part in integrating a number of popular clouds with RightScale (a web-based platform for managing cloud infrastructures from multiple providers). His interests embrace building IoT solutions powered by cloud technologies and designing architectures that meet customer needs. Check out Alexander\u2019s profile on GitHub.","url":"https:\/\/www.altoros.com\/blog\/author\/alexander-sologub\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/39167","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=39167"}],"version-history":[{"count":7,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/39167\/revisions"}],"predecessor-version":[{"id":44044,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/39167\/revisions\/44044"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/39168"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=39167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=39167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=39167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}