DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

Project: Serverless Orders + Profiles part 2

This project implements a fully serverless Order Processing system on AWS:

- Users can create profiles.
- Users can place orders.
- Orders trigger a Step Functions workflow:
    1) Validate order data
    2) Reserve inventory
    3) Charge payment
    4) Confirm order
- All order & profile data is stored in DynamoDB.
- Everything is exposed via API Gateway as REST endpoints.
- CI/CD pipeline automatically deploys Lambda code from GitHub → AWS.
Enter fullscreen mode Exit fullscreen mode

2) Architecture Diagram

     (Client / UI / Postman)
                |
        +----------------+
        | API Gateway    |
        +----------------+
           |     |     |
   POST /profiles   POST /orders   GET /orders/{id}
           |     |     |
           |     |     |
       create-profile   create-order
                         |
                         v
                   Step Functions Workflow
                +------- Validate -------+
                |                        |
                v                        v
            Reserve Lambda  →  Charge Lambda  →  Confirm Lambda
                |                        |
                +---------- Writes to DynamoDB --------+
Enter fullscreen mode Exit fullscreen mode

3) DynamoDB Tables

Table Name Partition Key Used For
profiles userId (String) Store user profiles
order orderId (String) Store each order record

Ensure order table name is lowercase: order


4) Lambda Functions (Final Code)

4.1 validate-order

import json

def lambda_handler(event, context):
    # Just return the input to pass to next state
    return event
Enter fullscreen mode Exit fullscreen mode

4.2 reserve-inventory

import boto3
import json

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('order')

def lambda_handler(event, context):
    event["status"] = "IN_PROGRESS"
    table.put_item(Item=event)
    return event
Enter fullscreen mode Exit fullscreen mode

4.3 charge-payment

import json

def lambda_handler(event, context):
    event["payment_status"] = "PAID"
    return event
Enter fullscreen mode Exit fullscreen mode

4.4 confirm-order

import boto3

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('order')

def lambda_handler(event, context):
    event["status"] = "CONFIRMED"
    table.put_item(Item=event)
    return event
Enter fullscreen mode Exit fullscreen mode

4.5 create-profile

import json
import boto3

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('profiles')

def lambda_handler(event, context):
    body = json.loads(event["body"])
    table.put_item(Item=body)
    return {"statusCode": 200, "body": json.dumps(body)}
Enter fullscreen mode Exit fullscreen mode

4.6 create-order (starts step function)

import json
import boto3
import os

sfn = boto3.client('stepfunctions', region_name='us-east-1')
STATE_MACHINE_ARN = os.environ['STATE_MACHINE_ARN']

def lambda_handler(event, context):
    body = json.loads(event["body"])
    sfn.start_execution(stateMachineArn=STATE_MACHINE_ARN, input=json.dumps(body))
    return {"statusCode": 200, "body": json.dumps({"message": "Order started"})}
Enter fullscreen mode Exit fullscreen mode

4.7 get-order

import json
import boto3

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('order')

def lambda_handler(event, context):
    orderId = event["pathParameters"]["id"]
    response = table.get_item(Key={"orderId": orderId})
    return {"statusCode": 200, "body": json.dumps(response.get("Item", {}))}
Enter fullscreen mode Exit fullscreen mode

5) Step Functions Definition (Copy-Paste)

{
  "Comment": "Serverless Order Processing",
  "StartAt": "Validate",
  "States": {
    "Validate": {
      "Type": "Task",
      "Resource": "<VALIDATE_LAMBDA_ARN>",
      "Next": "Reserve"
    },
    "Reserve": {
      "Type": "Task",
      "Resource": "<RESERVE_LAMBDA_ARN>",
      "Next": "Charge"
    },
    "Charge": {
      "Type": "Task",
      "Resource": "<CHARGE_LAMBDA_ARN>",
      "Next": "Confirm"
    },
    "Confirm": {
      "Type": "Task",
      "Resource": "<CONFIRM_LAMBDA_ARN>",
      "End": true
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Replace ARN placeholders.


6) API Gateway Final Endpoints

Action Method URL
Create Profile POST /profiles
Create Order POST /orders
Get Order Status GET /orders/{id}

Deploy to prod stage.


7) Repo Structure (Copy-Paste)

serverless-orders/
│
├── lambdas/
│   ├── validate-order.py
│   ├── reserve-inventory.py
│   ├── charge-payment.py
│   ├── confirm-order.py
│   ├── create-profile.py
│   ├── create-order.py
│   └── get-order.py
│
└── .github/
    └── workflows/
        └── deploy.yml
Enter fullscreen mode Exit fullscreen mode

8) CI/CD Pipeline (GitHub Actions)

Create file:

.github/workflows/deploy.yml

name: Deploy Lambda Functions

on:
  push:
    branches: [ "main" ]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      - name: Deploy Lambdas
        run: |
          for f in lambdas/*.py; do
            FUNCTION_NAME=$(basename $f .py)
            zip $FUNCTION_NAME.zip $f
            aws lambda update-function-code --function-name $FUNCTION_NAME --zip-file fileb://$FUNCTION_NAME.zip
          done
Enter fullscreen mode Exit fullscreen mode

9) Set GitHub Secrets

Go to:
GitHub → Repo → Settings → Secrets → Actions → New Secret

Add:

AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
Enter fullscreen mode Exit fullscreen mode

Use IAM user with Lambda + Step Functions + DynamoDB permissions.


✅ Your project is now complete with:

  • Serverless backend
  • API Gateway
  • Step Functions workflow
  • DynamoDB storage
  • Full CI/CD deployment pipeline

Top comments (0)