Action basics
Creating Actions - Helloworld
Create a JavaScript file named 'hello.js' with these contents:
function main(params) { return {payload: 'Hello, ' + params.name + ' from ' + params.place}; }
The JavaScript file might contain additional functions. However, by convention, a function called
main
is the default entry point for the action.Create an action from the 'hello.js' JavaScript function naming it
hello
:ibmcloud fn action create hello hello.js
List all actions; it should show the
hello
action you just created:ibmcloud fn action list
actions <NAMESPACE>/hello private nodejs10
You can see the
hello
action you just created under your default NAMESPACE with implied access control provided by the platform.
Takeaways
No special code needed, developer just the codes their favorite language
Convention: "Main" entrypoint assumed (can alias "main" to any function)
No build step: Runtimes for all supported languages already resident in "invoker" clusters for immediate function "injection".
NodeJS inferred (latest runtime version); can explicitly set with
--kind
flagNamespaced: (default) installed into; allows underlying platform to apply IAM access control to any entity (Package, Action, Trigger, etc.)
Note: "update" action subcommand will update internal version of source code (allowing existing actions to complete with source code version in-flight)
Invoking Actions
You may invoke
your action in one of two modes:
blocking - which will wait for the result (i.e., request/response style) by specifying the
blocking
flag on the command-line.non-blocking - which will invoke the action immediately, but not wait for a response.
Regardless, invocations always provide an Activation ID which can be used later to lookup the action's response.
Blocking Invocations
A blocking invocation request will wait for the activation result to be available.
Invoke the
hello
action using the command-line as a blocking activation.ibmcloud fn action invoke --blocking hello
ok: invoked /_/hello with id 4479...
... "response": { "result": { "payload": "Hello, undefined from undefined" }, "size": 45, "status": "success", "success": true }, ...
Notes
The wait period is the lesser of 60 seconds or the action's configured time limit.
The Activation ID can always be used later to lookup the response.
Non-blocking invocations (Async)
A non-blocking invocation will invoke the action immediately, but not wait for a response.
If you don't need the action result right away, you can omit the --blocking
flag to make a non-blocking invocation. You can get the result later by using the Activation ID.
Invoke the
hello
Action using the command-line as a non-blocking activation.ibmcloud fn action invoke hello
ok: invoked /_/hello with id 6bf1f670ee614a7eb5af3c9fde813043
Retrieve the activation result
ibmcloud fn activation result 6bf1...
{ "payload": "Hello, undefined from undefined" }
Alternatively, retrieve the
--last
or-l
activation resultibmcloud fn activation result --last
{ "payload": "Hello, undefined from undefined" }
Retrieve the full activation record
ibmcloud fn activation get 6bf1..
ok: got activation 6bf1.. { ... "response": { "result": { "payload": "Hello world" }, "size": 25, "status": "success", "success": true }, ... }
Retrieve activation list
ibmcloud fn activation list -l 2
Datetime Activation ID Kind Start Duration Status Entity
y:m:d:hm:s 44794bd6... nodejs:10 cold 34s success <NAMESPACE>/hello:0.0.1
y:m:d:hm:s 6bf1f670... nodejs:10 warm 2ms success <NAMESPACE>/hello:0.0.1
Takeaways
Actions can be invoked directly using CLI
asynchronously: by default
synchronously:
--block
flag
System tracks each action invocation with as an "Activation" (record)
Lots of information about execution time/params, etc.
Passing Action Parameters
Event parameters can be passed to the action when it is invoked. Let's look at a sample action which uses the parameters to calculate the return values.
From command line using the --param
flag
--param
flagInvoke the
hello
action using explicit command-line parameters using the--param
flag.ibmcloud fn action invoke --result hello --param name Elrond --param place Rivendell
or using the
-p
short form:ibmcloud fn action invoke --result hello -p name Elrond -p place Rivendell
{ "payload": "Hello, Elrond from Rivendell" }
From parameter file using the --param-file
flag
--param-file
flagCreate a file named
parameters.json
containing the following JSON.{ "name": "Frodo", "place": "the Shire" }
Invoke the
hello
action using parameters from a JSON file.ibmcloud fn action invoke --result hello --param-file parameters.json -p name Bilbo
{ "payload": "Hello, Bilbo from the Shire" }
"Binding" parameter defaults to Action
Rather than pass all the parameters to an action every time, you can bind default parameters. Default parameters are stored in the platform and automatically passed in during each invocation.
Let's use the hello
action from our previous example and bind a default value for the place
parameter.
From command line using --param
--param
Update the action by using the --param
option to bind default parameter values.
ibmcloud fn action update hello --param place Rivendell
From parameter file using --param-file
--param-file
Passing parameters from a file requires the creation of a file containing the desired content in JSON format. The filename must then be passed to the --param-file
flag:
Example: parameter file parameters2.json
:
parameters2.json
:{
"place": "Rivendell"
}
ibmcloud fn action update hello --param-file parameters2.json
Invoke the action, passing only the name
parameter this time.
ibmcloud fn action invoke --result hello --param name Elrond
{
"payload": "Hello, Elrond from Rivendell"
}
Notice that you did not need to specify the place parameter when you invoked the action.
Command Line overrides defaults (binding values)
Invoke the action, passing both name
and place
values. The latter overwrites the value that is bound to the action.
ibmcloud fn action invoke --result hello --param name Elrond --param place "the Lonely Mountain"
{
"payload": "Hello, Elrond from the Lonely Mountain"
}
Actions calling other Actions
Proxy example
Let's look an example of creating a "proxy" action which invokes another action (i.e, our hello
action) if a "password" is present in the input parameters.
Create the following new action named
proxy
from the following source files.var openwhisk = require('openwhisk'); function main(params) { if (params.password !== 'secret') { throw new Error("Password incorrect!") } var ow = openwhisk(); return ow.actions.invoke({name: "hello", blocking: true, result: true, params: params}) }
ibmcloud fn action create proxy proxy.js
Invoke the proxy with an incorrect password.
ibmcloud fn action invoke proxy -p password wrong -r
{ "error": "An error has occurred: Error: Password incorrect!" }
Invoke the proxy with the correct password.
ibmcloud fn action invoke proxy -p password secret -p name Bernie -p place Vermont -r
{ "greeting": "Hello Bernie from Vermont" }
Review the activations list to show both actions were invoked.
ibmcloud fn activation list -l 2
Activation ID Kind Start Duration Status Entity 8387302c81dc4d2d87302c81dc4d2dc6 nodejs:10 cold 35ms success hello:0.0.4 e0c603c242c646978603c242c6c6977f nodejs:10 cold 438ms success proxy:0.0.1
Takeaways
Platform functions simplified:
Simple import of NPM package (NodeJS developer familiar)
NPM Apache OpenWhisk JavaScript library
Actions call other actions
Last updated
Was this helpful?