DEV Community

عبدالله عياد | Abdullah Ayad for AWS Community Builders

Posted on • Edited on

Lambda Function (Part 3)

-------------- See part 2 from here ----------------

Creating Conditional Step Type

Introduction

In the other branch of the parallel task, you need to update the DynamoDB tables.

In many scenarios, the flow is dependent upon a choice. In order to fulfill this requirement, AWS Step Functions provides a Choice step.

The second branch starts with the UpdateDB task and its type is choice. This means that when the flow arrives here, a choice has to be made, and it is up to AWS Step Functions to make that choice. The next step that gets executed is based on the choice.

In the Choices field on line 6, you would typically declare a series of comparisons. In this case, there are only two possibilities so there would need to be one comparison declared, using the Default field that explains which task to run in case no condition is satisfied. The conditional step template is shown below. Note: remember that this is just part of the larger JSON template.

{
    "StartAt": "UpdateDB",
    "States": {
        "UpdateDB": {
            "Type": "Choice",
            "Choices": [{
                "Variable": "$.level",
                "StringEquals": "latest",
                "Next": "Last Level"
            }],
            "Default": "Simple Level"
        },
        "Last Level": {
            "Type": "Task",
            "Resource": "arn:aws:lambda:us-west-2:ACCOUNT_ID:function:EndsLastLevel",
            "End": true
        },
        "Simple Level": {
            "Type": "Task",
            "Resource": "arn:aws:lambda:us-west-2:ACCOUNT_ID:function:EndsSimpleLevel",
            "End": true
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

A choice is made up of at least three fields:

Variable: The variable that needs to be evaluated, defined using JMESpath

  • Kind of comparison: AWS provides different kinds of comparisons, based on the type of the variable
  • Next: The name of the task that will be executed in case the comparison result is true
  • Note: Remember that only the first evaluation that is true is going to be executed.

In this case, $.level variable is evaluated. With the comparison StringEquals you check if its value is "latest". In this case, the Last Level task will be executed, otherwise, the Simple Level will be excecuted instead.

AWS Step Functions handles this flow efficiently by only requiring it declared in the template, such that no additional code or Lambda function is required.

There are many more kinds of comparisons available that are self-explanatory. For example:

String comparisons:

StringEquals
StringLessThan
StringGreaterThan
StringLessThanEquals
StringGreaterThanEquals

Number comparisons:

NumericEquals
NumericLessThan
NumericGreaterThan
NumericLessThanEquals
NumericGreaterThanEquals

Boolean comparisons: BooleanEquals.

And arguably the most powerful: Timestamp conditions:

TimestampEquals
TimestampLessThan
TimestampGreaterThan
TimestampLessThanEquals
TimestampGreaterThanEquals

In addition, for more structured and complex conditions, you can use the boolean operators like And, Or, and Not as well.

Now you have to implement functions to handle database updates. To create a completely serverless architecture, you will use DynamoDB to store your information.

In this step you are going to create two Lambda functions:

  • EndsSimpleLevel: This function will be called when the user ends a simple level, not the latest level
  • EndsLastLevel: This function will be called when the user completes the last level

Instructions

  1. In the AWS Management Console search bar, enter Lambda, and click the Lambda result under Services:

  2. Click on Create function.

  3. Check Author from scratch and fill all fields as given below:

  • Function name: EndsSimpleLevel
  • Runtime: Python 3.7
  1. Toggle the drop-down Change default execution role and fill all fields as given below:

Select the role or create your own

  1. Click Create function.

  2. Move into the Code source section and double-click lambda_function.py, replacing the contents with the code below

import time
import boto3
dynamodb_client = boto3.client('dynamodb')
table_name = 'CompletedLevel'
def lambda_handler(event, context):
    user_id = event.get('user_id')
    level = event.get('level')
    update_params = {
        "TableName": table_name,
        "Key": {
            "user_id": {
                "S": user_id
            }
        },
        "AttributeUpdates": {
            "last_level": {
                "Value": {
                    "S": level
                },
                "Action": "PUT"
            },
            "timestamp": {
                "Value": {
                    "S": str(time.time())
                },
                "Action": "PUT"
            }
        }
    }
    dynamodb_client.update_item(**update_params)
    return event
Enter fullscreen mode Exit fullscreen mode

As you can see, the code is pretty simple. It calls the update_item API on the CompletedLevel table and terminates the function returning the event received. As mentioned before, the result of each function is very important because it's either what the next function will receive at the start of its flow, or the result of the entire execution.

  1. To deploy your function, click Deploy.

You should now have two Lambda functions created for this lab. Now you will create the third and final Lambda function.

  1. Navigate back to the Lambda console. In the AWS Management Console search bar, enter Lambda, and click the Lambda result under Services:

  2. Click on Create function.

  3. Check Author from scratch and fill all fields as given below:

Function name: EndsLastLevel
Runtime: Python 3.7

  1. Toggle the drop-down Change default execution role and fill all fields as given below:

Select the role or create your own

  1. Click Create function.

  2. Move into the Code source section and double-click lambda_function.py, replacing the contents with the code below:

import boto3
import time
table_name = 'CompletedGame'
dynamodb_client = boto3.client('dynamodb')
def lambda_handler(event, context):
    user_id = event.get('user_id')
    total_score = event.get('total_score')
    put_params = {
        "TableName": table_name,
        "Item": {
            "user_id": {
                "S": user_id
            },
            "completed": {
                "BOOL": True
            },
            "timestamp": {
                "S": str(time.time())
            },
            "total_score": {
                "N": str(total_score)
            }
        }
    }
    dynamodb_client.put_item(**put_params)
    return event
Enter fullscreen mode Exit fullscreen mode

This code is quite simple too. It calls the DynamoDB put_item API on the other table (CompleteLevel) and terminates returning the event received.

  1. To deploy your function, click Deploy.

In the next step, you will create the last task that completes your flow.

Logging Results to CloudWatch

See the final part (part 4) from here

GitHub
LinkedIn
Facebook
Medium

Top comments (0)