3-tier-arch-serverless / app / server / index.mjs
index.mjs
Raw
import AWS from 'aws-sdk'

AWS.config.update({
    region: 'us-east-1'
})

// Get dynamodb table
const dynamodb = new AWS.DynamoDB.DocumentClient()
const dynamodbTableName = 'users-api'

// Initialize paths
const healthPath = '/health'
const userPath = '/user'
//const usersPath = '/users'

// Define lambda handler
export const handler = async (event) => {
    let response
    switch (true) {
        case event.httpMethod === 'GET' && event.path === healthPath:
            response = buildResponse(200, 'Application is healthy')
            break;
        /*case event.httpMethod === 'GET' && event.path === userPath:
            response = getUser(JSON.parse(event.body).email)
            break;
        case event.httpMethod === 'GET' && event.path === usersPath:
            response = getAllUsers()
            break;*/
        case event.httpMethod === 'POST' && event.path === userPath:
            response = addUser(JSON.parse(event.body))
            break;
        default:
            response = buildResponse(404, 'Not found')
            break;
    }
    return response
}

const addUser = async (eventBody) => {
    // First do a validation of all required fields here...before
    if (eventBody.email === "") {
        return buildResponse(400, 'no_email')
    }else if (eventBody.username === "") {
        return buildResponse(400, 'no_username')
    }
    const params = {
        TableName: dynamodbTableName,
        Item: eventBody,
        ConditionExpression: "attribute_not_exists(email)"
    }
    return await dynamodb.put(params).promise().then((response) => {
        const postBody = {
            message: 'user_added',
            item: eventBody
        }
        //return buildResponse(200, postBody)
        return getAllUsers(postBody)
    }, (error) => {
        console.log(`error: ${error}`)
        if (error.code === "ConditionalCheckFailedException") {
            return buildResponse(400, 'user_exist')
        }
        return buildResponse(500, 'server_error')
    })
}

const getUser = async (email) => {
    const params = {
        TableName: dynamodbTableName,
        Key: {
            'email': email
        }
    }
    let body = {}
    return await dynamodb.get(params).promise().then((response) => {
        if (response.Item) {
            body.user = response.Item
        }
        //return buildResponse(200, body)
        return body
    }, (error) => {
        console.error(`Unable to fetch user with email ${email} : ${error}`)
        return buildResponse(500, 'server_error')
    })
}

const getAllUsers = async (postBody) => {
    try {
        const itemsArray = []
        const scanDynamoRecords = async (lastEvaluatedKey = undefined) => {
            const { Items = [], LastEvaluatedKey } = await dynamodb
            .scan({
            TableName: dynamodbTableName,
            ExclusiveStartKey: lastEvaluatedKey
            })
            .promise()        
            itemsArray.push(...Items.map((item) => item))  
            if (LastEvaluatedKey) {
                await scanDynamoRecords(LastEvaluatedKey)
            }
        }  
        await scanDynamoRecords()
        const body = {
            postBody: postBody,
            allUsers: itemsArray
        }
        return buildResponse(200, body)
    }catch(error) {
        return buildResponse(500, 'server_error')
    }
}

const buildResponse = (statusCode, body) => {
    return {
        statusCode: statusCode,
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(body)
    }
}