blob: 82a692c5e51aeeffc88a2ad9f2b33e914e2ac710 [file] [log] [blame] [view]
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
-->
## Creating and invoking Rust actions
The process of creating Rust actions is similar to that of [other actions](actions.md#the-basics).
The following sections guide you through creating and invoking a single Rust action,
and demonstrate how to bundle multiple Rust files and third party dependencies.
An example action Rust action is simply a top-level function.
For example, create a file called `hello.rs` with the following source code:
```Rust
extern crate serde_json;
use serde_derive::{Deserialize, Serialize};
use serde_json::{Error, Value};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct Input {
#[serde(default = "stranger")]
name: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct Output {
greeting: String,
}
fn stranger() -> String {
"stranger".to_string()
}
pub fn main(args: Value) -> Result<Value, Error> {
let input: Input = serde_json::from_value(args)?;
let output = Output {
greeting: format!("Hello, {}", input.name),
};
serde_json::to_value(output)
}
```
Rust actions are mainly composed by a `main` function that accepts a JSON `serdes Value` as input and returns a `Result` including a JSON `serde Value`.
An action supports not only a JSON object but also a JSON array as a return value.
It would be a simple example that uses an array as a return value:
```rust
extern crate serde_json;
use serde_derive::{Deserialize, Serialize};
use serde_json::{Error, Value};
pub fn main(args: Value) -> Result<Value, Error> {
let output = ["a", "b"];
serde_json::to_value(output)
}
```
You can also create a sequence action with actions accepting an array param and returning an array result.
You can easily figure out the parameters with the following example:
```rust
extern crate serde_json;
use serde_derive::{Deserialize, Serialize};
use serde_json::{Error, Value};
pub fn main(args: Value) -> Result<Value, Error> {
let inputParam = args.as_array();
let defaultOutput = ["c", "d"];
match inputParam {
None => serde_json::to_value(defaultOutput),
Some(x) => serde_json::to_value(x),
}
}
```
The entry method for the action is `main` by default but may be specified explicitly when creating
the action with the `wsk` CLI using `--main`, as with any other action type.
You can create an OpenWhisk action called `helloRust` from this function as follows:
```
wsk action create helloRust --kind rust:1.34 hello.rs
```
The CLI automatically infers the type of the action from the source file extension.
For `.rs` source files, the action runs using a Rust v1.34 runtime.
Action invocation is the same for Rust actions as it is for any other actions:
```
wsk action invoke --result helloRust --param name World
```
```json
{
"greeting": "Hello World!"
}
```
Find out more about parameters in the [Working with parameters](./parameters.md) section.
## Packaging Rust actions in zip files
If your action needs external dependencies, you need to provide a zip file including your source and your cargo file with all your dependencies.
The filename of the source file containing the entry point (e.g., `main`) must be `lib.rs`.
The folder structure should be as follows:
```
|- Cargo.toml
|- src
|- lib.rs
```
Here is an example of a Cargo.toml file
```
[package]
name = "actions"
version = "0.1.0"
authors = ["John Doe <john@doe.com>"]
edition = "2018"
[dependencies]
serde_json = "1.0"
serde = "1.0"
serde_derive = "1.0"
```
To zip your folder:
```bash
zip -r helloRust.zip Cargo.toml src
```
and then create the action:
```bash
wsk action create helloRust --kind rust:1.34 helloRust.zip
```