On this page:
For your code to execute as an action on Adobe I/O Runtime, your code has to comply with two rules:
You have to configure two tools on your machine to create and invoke actions from your machine: wsk CLI and wskdeploy CLI. Refer to the wsk CLI page for how to install and configure it.
Let’s assume you have this function available on your machine:
// this is saved in a file named first-function.js
function main(params) {
var nm = params.name || 'stranger';
return {payload: 'Hello ' + nm};
}
exports.main = main;
You can create an action called test using this command:
wsk action create test first-function.js
You can update an action at any time using the following command:
wsk action update test first-function.js
If you don’t need an action anymore, you can delete it:
wsk action delete test
If you want to save an action that is deployed to your machine, then you can use this command:
wsk action get test --save
Listing all the available actions in your current namespace is as simple as running this command:
wsk action list
Now, that you have an action, you can call it using the following command (in this example the action name is test):
wsk action invoke test --result
Note the flag –result used in the command. This flag outputs the result of the invocation. Without it, instead of seeing the result of the invocation, you’d get the activation ID. To get the result, you’d use this ID to retrieve the result like this:
wsk activation get <activation ID>
When you invoke an action, as in the example above, the invocation is not blocking (it is async). If you want to execute it in a blocking style and, as a result, get the activation record instead of just getting an activation ID, you have to add the –blocking flag to the command:
wsk action invoke test --blocking
Actions can receive parameters when are being executed. First, any parameters you sent to the action will be available through the params variable. If you send two parameters called first-name and last-name, they will be available as params.first-name and params.last-name.
Second, let’s see how you can invoke the action with parameters. Our function sample from above uses a parameter called name. This is how you can set the parameter when invoking the action:
wsk action invoke test --param name "John Doe" --result
Sometimes you want to bind the same parameter values for all invocations or you just want to set default values. In either case, you have two different options: setting params at the package level (so all actions in that package can inherit them) or at action level.
Before we dive deeper in how to set and use default params, let’s discuss the security aspect first. Many developers use the default params as a mechanism to provision actions with the secrets/passwords needed to authenticate against some other systems (databases, services, APIs).
In order to support this use case, all default params are automatically encrypted. They are decrypted just before the action code is executed. Thus, the only time you have access to the decrypted value is while executing the action code.
If you run the CLI command for getting an action or package, you’d get a listing for the names of the default params while the values will be listed as a hash instead of the actual value.
Let’s assume that you want the default value of your parameter to be “Runtime”. You can set this value when creating the action, or if the action already exists, updating the action. In both cases you add the *–param” flag:
// creation time
wsk action create test first-function.js --param name "Runtime"
// update
wsk action update test first-function.js --param name "Runtime"
Now, you can run the action without any parameters, and it will use the default one you’ve set. If you set a parameter when invoking, this will overwrite the default one.
When you create an action, it is always created in a package. If you don’t specify a package, the default package is used. Similar to how you set default parameters at the action level, you can specify default parameters at the package level.
The difference is that the params set at the package level will be used for all the actions you create in that package.
// creation time
wsk package create my-package --param name "Runtime"
// update
wsk package update my-package --param name "Runtime"
At this point, you might ask yourself what is the precedence when setting parameters at the package level, action level, and invocation time. The winner is parameters set at invocation time, followed by parameters set at action level, and the last is parameters set at package level.
A neat way for setting default params is using a dedicated file for storing their values, and then using this file to set those values as default parameter values.
This is especially useful when you are dealing with multiple parameter values for things like configuring API access keys, endpoints, and so on.
Coming back to our sample function that expects one parameter, name, you’d create a JSON file to store that value:
// filename is my-params.json
{
"name": "Runtime"
}
Then, you use the –param-file flag when creating actions, creating packages, or invoking actions.
// update action
wsk action update test first-function.js --param-file my-params.json
// invoke action
wsk action invoke test --param-file my-params.json
Sometimes, an application needs to ensure that the default parameters are final (or immutable), and a calling client can’t override them. You can achieve this by adding the final
annotation - -a final true
:
wsk action update test first-function.js --web true --param name "Runtime" -a final true
This mechanism works for all type of actions including web actions.
So far, we’ve been invoking actions only from the CLI. While this might be good for trying out your actions, as you design actions for production systems, you might need to be able to invoke actions via HTTP REST calls. This would enable you to invoke the actions from your web application.
You create a web action by adding the –web flag to the wsk action command:
// creation time
wsk action create test first-function.js --web true
// update
wsk action update test first-function.js --web true
Notice the true value used in the command. If you set that value to false, then you disable a web action.
To call the action as a web action, you need to know the full path to the action. You can find the path by adding the –url flag to the action command:
wsk action get test --url
This will give you something like:
ok: got action test
https://adobeioruntime.net/api/v1/web/[your namespace]/default/test
In the URL above, the default
in the path stands for the default
package: if you don’t create your actions explicitly in a package, then they get under the default
package.
You can invoke the action like this:
curl -L https://adobeioruntime.net/api/v1/web/[your namespace]/default/test -x GET
or
curl https://[your namespace].adobeioruntime.net/api/v1/web/default/test -x GET
Note the change in the URL here in comparison to what the wsk
returns. This is due some additional protections Runtime provides to segregate namespaces from each other when invoking web actions. The wsk
generated link will still work but it will return a 308 redirect to your namespace’s subdomain on Runtime. For a further discussion of this please see the Securing Web Actions page.
When creating actions to be used as web actions, you might want to send the response that follows the HTTP response structure (status code, headers, body). For example, our sample function could be rewritten:
function main(params) {
var nm = params.name || 'stranger';
return {
statusCode: 200,
body: {
payload: 'Hello ' + nm
}
}
}
exports.main = main;
You can also set cookies or cache control headers, perform a HTTP redirect, and so forth.
When executing an action as a web action, the params
object is decorated with additional information:
Method | Description |
---|---|
__ow_method |
the HTTP method of the request |
__ow_headers |
the request headers |
__ow_path |
the unmatched path of the request (matching stops after consuming the action extension) |
__ow_body |
the request body entity, as a base64-encoded string when its content is binary or JSON object/array, or as a plain string otherwise |
__ow_query |
the query parameters from the request as an unparsed string |
By default, web actions are accessible to anyone who knows the URL. If you want to secure the access, you can find more info on the Securing Web Actions page.
So far, we’ve been creating actions from a single source file. What if you need to create an action from multiple files and you also need some npm modules? The answer is deploying a ZIP action.
You need to do three things to deploy a ZIP action: create a manifest file, create the package.json file, and configure/use wskdeploy
instead of wsk
for the actual deploy.
If you need to install wskdeploy
, check the page Setting up the wskdeploy CLI.
You use the package.json file to specify the dependencies. If you don’t have one already, in the same folder where your function files are, run npm init -y
.
Make sure you have the npm dependencies you need for your functions declared in the package file.
The last step is creating the manifest file that will be used by wskdeploy to create your action. In the parent folder of the folder where you have your function files and npm modules, create a file manifest.yaml
. (For more information on YAML format, see the YAML reference card.)
This is the folder structure:
--/actions
--/actions/node_modules/
--/actions/index.js
--/actions/package.json
--manifest.yaml
Here is an example manifest.yaml:
packages:
# this is the package name
test:
actions:
# name of the action
test-zip:
# source for the action; in this case it is a folder
function: actions
runtime: nodejs:10
# publish the action as a web action
web: yes
Note: If your action require dependencies (such as other node modules or JavaScript files), you need to place the action code in a
index.js
file and in themanifest.yaml
file, thefunction
value should point to the folder where the action is stored instead of the action file. You can see this in action in the example above.
Now you are ready to deploy by running the wskdeploy
command from the same folder where manifest.yaml
is:
wskdeploy
This should deploy an action called test-zip under a package called test. You can invoke it like this:
wsk action invoke test/test-zip --result
If you want to remove this action, you run wskdeploy
with the undeploy flag:
wskdeploy undeploy
There are other useful flows wskdeploy
supports. Please check the official documentation if you want to find more.
Note: There is another way of deploying a ZIP action using the wsk command. You miss the manifest.yaml file flexibility with this mode; you can’t define multiple actions/packages at the same time. The ZIP file has to have in the root the package.json file.
wsk action create my-action --kind nodejs:10 zip-file.zip