If you've gone through our technical overview, you can see how steps are built in any language. Even though the process is fairly straightforward, we felt it was important to provided a thin SDK to improve the speed and debugging ability of building new packages. Right now we have SDKs for:
Go
C#
Luckily, because our SDK layer is so thin, it's easy for us (or you) to build a new one for the language of your choice.
There are a few important advantages to utilizing our SDKs.
You don't need to worry about how to parse inputs or return outputs
You can run your package in hosted
mode. In this mode, your package will be run in a mini server allowing the engine to call it as part of a workflow. This let's you set breakpoints and debug your step while running in a real workflow.
You can interact with the AppTree Cache directly from your step. Allowing you to query and insert data from your step into our caching layer.
Here you can see a quick example of using the SDK in Go and C#. We attempt to keep the SDK as idiomatic as possible to the language you are using.
main.go// (1)type StringLengthInput struct {Text string}​type StringLengthOutput struct {Count int}​// (2)type StringLengthCounter struct {}​// Implements the Step interfacefunc (StringLengthCounter) Name() string {return "string_length"}​// Implements the Step interfacefunc (StringLengthCounter) Version() string {return "1.0"}// Implements the Step interfacefunc (StringLengthCounter) Execute(ctx step.Context) (interface{}, error) {input := StringLengthInput{}err := ctx.BindInputs(&input) // 3if err != nil {return nil, err}// 4output := StringLengthOutput{}output.Count = len(input.Text)return output, nil}​//func main() {step.Register(StringLengthCounter{}) // 5step.Run() // 6}​
We first declare our input and output structs. Remember, the engine will send all input as JSON so you simply need to create a struct that contains the input
fields you want to read in. In this case, we have one input which is Text
.
Next we declare our Step StringLengthCounter
struct and have it implement the Step
interface which has 3 methods:
Name() string
Version() string
Execute(ctx step.Context) (interface{}, error)
In the execute method, we we are passed in a step.Context
which contains information about the environment it's running in. It also has some convenience methods like Bind
that will read the inputs into the struct provided.
Next we count the string and assign it to our StringLengthOutput
struct. When this struct is returned from the Execute
method it will be serialized as JSON and sent back to the engine for us by the SDK
Using the SDK, we register the step.
Lastly, the step.Run()
method executes your step packages taking care of things for you like determining which step to run, parsing inputs, etc.
An example string_length
step in C# using the C# SDK. The C# SDK makes use of Attributes to simplify the development and registration of the step.
StringLength.cs[StepDescription("string_length")] // (1)public class StringLength : Step{ // (2)// (3)[Input(Description = "The string you want to count the length of")]public string Text { get; set; }// (4)[Output(Description = "The length of the string")]public int Length { get; set; }// (5)public override void Execute() {var length = this.text.length;this.Length = length;}}
Program.csusing System;using System.Threading.Tasks;using StepCore;​namespace Accruent.Famis.Steps {// (6)[PackageDefinition("StringUtils")]class Program {static async Task Main(string[] args) {await PackageManager.Run(args); //(7)}}}