DEV Community

Cover image for Use StepFunctions to simplify your serverless applications
Joris Conijn for AWS Community Builders

Posted on • Originally published at xebia.com

Use StepFunctions to simplify your serverless applications

AWS StepFunctions is a great orchestrating tool for your serverless applications. When you write lambda functions that only contain logic to perform a single task they are easier to test. Especially when there is no orchestration logic within your function. 

The orchestration is then performed by StepFunctions by defining a state machine. This state machine is nothing more than a JSON definition based on Amazon State Language. It describes the flow between the functions for your specific use-case.

Lets use an example

Lets say one of the input parameters is an object location on S3. We will feed this to your state machine. A lambda function can then be used to read this object and perform some business logic on this data.

Or you can use the AWS SDK Service integration. By using the service integration you can again simplify your business logic. Instead of needing to read an object from S3 and do some actions. You only need to do the action on the data that you receive. This will remove the need of mocking S3 GetObject calls in your unit tests. Next to that you do not have to pay for the time it takes to read the data from S3. This is done outside of the scope of the lambda function, and therefor you do not have to pay for it.

Sounds great, do you have an example for me?

Lets assume the following payload it given:

{
  "Bucket": "my-bucket-name",
  "ObjectKey": "my-path/to-my-file.json"
}
Enter fullscreen mode Exit fullscreen mode

And we have a the following task in our state machine:

{
  "Read From S3": {
    "Type": "Task",
    "Resource": "arn:aws:states:::aws-sdk:s3:getObject",
    "Parameters": {
      "Bucket": "$.Bucket",
      "Key": "$.ObjectKey"
    },
    "OutputPath": "$.Body",
    "ResultPath": "$.ObjectBody",
    "Next": "My Lambda"
  }
}
Enter fullscreen mode Exit fullscreen mode

This will perform a s3:getObject action on s3://my-bucket-name/my-path/to-my-file.json. The action returns the content of the file in the Body parameter. And we will place this content in the  ObjectBody parameter of the event. So the event will now look like:

{
  "Bucket": "my-bucket-name",
  "ObjectKey": "my-path/to-my-file.json",
  "ObjectBody": "{\"Foo\": \"Bar\"}",
  "TransformedBody": "{\"Foo\": \"Bar\"}"
}
Enter fullscreen mode Exit fullscreen mode

We can now invoke a lambda function to do something with this payload:

{
  "My Lambda": {
    "Type": "Task",
    "Resource": "arn:aws:states:::lambda:invoke",
    "InputPath": "$.ObjectBody",
    "Parameters": {
      "FunctionName": "arn:aws:lambda:eu-west-1:123456789012:function:my-function"
    },
    "ResultPath": "$.TransformedBody",
    "Next": "Write to S3"
  }
}
Enter fullscreen mode Exit fullscreen mode

Assume that in the lambda function we enriched the object with an extra parameter. So the event will look like this now:

{
  "Bucket": "my-bucket-name",
  "ObjectKey": "my-path/to-my-file.json",
  "ObjectBody": "{\"Foo\": \"Bar\"}",
  "TransformedBody": "{\"Foo\": \"Bar\", \"Bar\": \"Foo\"}"
}
Enter fullscreen mode Exit fullscreen mode

We can now store the transformed event on S3:

{
  "Write to S3": {
    "Type": "Task",
    "Resource": "arn:aws:states:::aws-sdk:s3:putObject",
    "Parameters": {
      "Bucket": "$.Bucket",
      "Key": "$.ObjectKey",
      "Body.$": "$.TransformedBody"
    }
  },
  "End": true
}
Enter fullscreen mode Exit fullscreen mode

And done, the existing object is updated with the extra parameter in the json structure.

Conclusion 

You can use StepFunctions to remove the following from your lambda functions:

  • Orchestration logic
  • AWS API Calls

This enables you to focus on the task at hand, and simplifies the code that you need to write and maintain.

Photo by Baskin Creative Studios

Top comments (0)