DEV Community 👩‍💻👨‍💻

Cover image for Creating users on DynamoDB with Step Functions

Creating users on DynamoDB with Step Functions

Step-Functions has enabled endless serverless orchestrations with the 200+ SDK integrations.
In this blog-post we will look into a simple DynamoDB operations QUERY and PUTITEM.

Step Functions workflow

In this workflow, we will use states which integrates with DynamoDB SDK APIs.
Workflow

{
  "Comment": "A description of my state machine",
  "StartAt": "CheckIfUserExists",
  "States": {
    "CheckIfUserExists": {
      "Type": "Task",
      "Parameters": {
        "TableName": "UsersDemo",
        "IndexName": "email_id-index",
        "KeyConditionExpression": "email_id = :email_id",
        "ExpressionAttributeValues": {
          ":email_id": {
            "S.$": "$.email"
          }
        }
      },
      "Resource": "arn:aws:states:::aws-sdk:dynamodb:query",
      "Next": "Choice",
      "ResultPath": "$.checkIfUserExists"
    },
    "Choice": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.checkIfUserExists.Count",
          "NumericEquals": 0,
          "Next": "CreateUserOnDynamoDB"
        }
      ],
      "Default": "Pass"
    },
    "CreateUserOnDynamoDB": {
      "Type": "Task",
      "Resource": "arn:aws:states:::dynamodb:putItem",
      "Parameters": {
        "TableName": "UsersDemo",
        "Item": {
          "pk": {
            "S.$": "$.id"
          },
          "email_id": {
            "S.$": "$.email"
          }
        }
      },
      "ResultPath": "$.dynamodbPut",
      "End": true
    },
    "Pass": {
      "Type": "Pass",
      "End": true,
      "Result": {},
      "ResultPath": "$.response"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

In the first step, we will do a DynamoDB query with an Index.
Step1
The JSON definition shows DynamoDB query API input JSON mapping to the email which is passed as an input. The SDK integration makes it simple in-terms of how the SDK API expects parameters -

{
  "TableName": "UsersDemo",
  "IndexName": "email_id-index",
  "KeyConditionExpression": "email_id = :email_id",
  "ExpressionAttributeValues": {
    ":email_id": {
      "S.$": "$.email"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

In this you can see that API parameter is same as how you would use in your application code, just that the value of email_id in ExpressionAttributeValues is taken from StepFunctions invocation event.
On the query response, it returns the structure how it returns with SDK integration with application code, with a JSON object which has Count and Items.
Choice
With the response, you can check if Count is equal to 0 or not, if it is 0, that means there is no item on DynamoDB with the email_id which was sent as input. Based on this there is a StepFunction choice defined to transition into CreateUserOnDynamoDB step only if Count == 0 otherwise pass the state to end.
Whenever the Count==0, the state transitions into another DynamoDB action based step where PUT API of DynamoDB is integrated with StepFunctions and DynamoDB SDK integration.
CreateUserOnDynamoDB step
In this step too, the SDK parameters for put is used with the JSON values of id and email_id taken from the StepFunctions event.

{
  "TableName": "UsersDemo",
  "Item": {
    "pk": {
      "S.$": "$.id"
    },
    "email_id": {
      "S.$": "$.email"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Once the DynamoDB put responds with success, the execution of StepFunctions is also successfully ended.

Note : Whenever in the SDK API parameters which are fetching the details from either previous step's response or the event JSON itself, the attribute should be suffixed with .$ and the variable name from the JSON prefixed with $.

Workflow executions

  • Scenario 1 : When user email doesn't exists.
    Scenario 1 : When user email doesn't exists
    The CheckIfUserExists of DynamoDB query returns the response with Count = 0 and thus satisfying the choice condition and then DynamoDB put operation in CreateUserOnDynamoDB the step takes input from previous step and also the StepFunctions invocation event and with successful put operation returns the DynamoDB response too.

  • Scenario 2 : When user email exists.
    Scenario 2 : When user email exists
    The CheckIfUserExists of DynamoDB query returns the response with Count = 1 and also the item in Items. With this input to the choice, it fails the choice condition and passes the flow to end.

Conclusion

With DynamoDB SDK integration that is supported by StepFunctions, it makes it easier for develops to construct their workflows and with minimal application coding, build your workflows and get the records created and queried from DynamoDB.

Top comments (2)

Collapse
girishjaju profile image
Girish Jaju

This is a good example showing API GW -> Step Fn -> DynamoDB.

I totally get that you are trying to demonstrate the capability of Step Functions directly integrating with DynamoDB.

I am a big fan of Step Functions, have been using them for over 5+ years in multiple production workflow scenarios.

It would probably be more cost effective to use API GW -> Lambda -> DynamoDB as the StepFunction StateMachine's State Transition costs much higher than Lambda invocation cost.

Thoughts?

Collapse
zachjonesnoel profile image
Jones Zachariah Noel Author

Hi @girishjaju,

Thanks for the feedback. 🙏

Yep this blog post is focused on StepFunctions and it's integration feature with DynamoDB SDK.

I do agree, StepFunctions makes a process flow more defined and helps in better integration with other services.

I've not gone too deep on cost comparison with Lambda fn code but my understanding is also that Lambda would be more cost effective. I will certainly look into it and probably create a blog post about cost comparison also. You can also share your insights!

Find what you were looking for? Join hundreds of thousands of developers on DEV so you can:

 
🌚 Enable dark mode
🔠 Change your default font
📚 Adjust your experience level to see more relevant content