Skip to content

Repository files navigation

AWS Project - Build a Full End-to-End Web Application with 7 Services

We're creating a web application for a unicorn ride-sharing service called Wild Rydes The app will let you create an account and log in, then request a ride by clicking on a map (powered by ArcGIS). The code can also be extended to build out more functionality.

Cost

All services used are eligible for the AWS Free Tier. Outside of the Free Tier, there may be small charges associated with building the app (less than $1 USD), but charges will continue to incur if you leave the app running. Please see the end of the YouTube video for instructions on how to delete all resources used in the video.

The Application Code

The application code is here in this repository.

The Lambda Function Code

Here is the code for the Lambda function, originally taken from the AWS workshop, and updated for Node 20.x:

import { randomBytes } from 'crypto';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient, PutCommand } from '@aws-sdk/lib-dynamodb';

const client = new DynamoDBClient({});
const ddb = DynamoDBDocumentClient.from(client);

const fleet = [
    { Name: 'Angel', Color: 'White', Gender: 'Female' },
    { Name: 'Gil', Color: 'White', Gender: 'Male' },
    { Name: 'Rocinante', Color: 'Yellow', Gender: 'Female' },
];

export const handler = async (event, context) => {
    if (!event.requestContext.authorizer) {
        return errorResponse('Authorization not configured', context.awsRequestId);
    }

    const rideId = toUrlString(randomBytes(16));
    console.log('Received event (', rideId, '): ', event);

    const username = event.requestContext.authorizer.claims['cognito:username'];
    const requestBody = JSON.parse(event.body);
    const pickupLocation = requestBody.PickupLocation;

    const unicorn = findUnicorn(pickupLocation);

    try {
        await recordRide(rideId, username, unicorn);
        return {
            statusCode: 201,
            body: JSON.stringify({
                RideId: rideId,
                Unicorn: unicorn,
                Eta: '30 seconds',
                Rider: username,
            }),
            headers: {
                'Access-Control-Allow-Origin': '*',
            },
        };
    } catch (err) {
        console.error(err);
        return errorResponse(err.message, context.awsRequestId);
    }
};

function findUnicorn(pickupLocation) {
    console.log('Finding unicorn for ', pickupLocation.Latitude, ', ', pickupLocation.Longitude);
    return fleet[Math.floor(Math.random() * fleet.length)];
}

async function recordRide(rideId, username, unicorn) {
    const params = {
        TableName: 'Rides',
        Item: {
            RideId: rideId,
            User: username,
            Unicorn: unicorn,
            RequestTime: new Date().toISOString(),
        },
    };
    await ddb.send(new PutCommand(params));
}

function toUrlString(buffer) {
    return buffer.toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}

function errorResponse(errorMessage, awsRequestId) {
    return {
        statusCode: 500,
        body: JSON.stringify({
            Error: errorMessage,
            Reference: awsRequestId,
        }),
        headers: {
            'Access-Control-Allow-Origin': '*',
        },
    };
}

The Lambda Function Test Function

Here is the code used to test the Lambda function:

{
    "path": "/ride",
    "httpMethod": "POST",
    "headers": {
        "Accept": "*/*",
        "Authorization": "eyJraWQiOiJLTzRVMWZs",
        "content-type": "application/json; charset=UTF-8"
    },
    "queryStringParameters": null,
    "pathParameters": null,
    "requestContext": {
        "authorizer": {
            "claims": {
                "cognito:username": "the_username"
            }
        }
    },
    "body": "{\"PickupLocation\":{\"Latitude\":47.6174755835663,\"Longitude\":-122.28837066650185}}"
}

Key Features

  • User Authentication: Managed with AWS Cognito.
  • Ride Matching: Randomly assigns a unicorn from a predefined fleet.
  • Backend Logic: Implemented using AWS Lambda (Node.js).
  • Data Persistence: Ride details stored in DynamoDB.
  • Scalable Design: Built using AWS Free Tier services with minimal costs (<$1 USD for non-free usage).

Technical Highlights

  • The backend assigns a unicorn to a user request based on the pickup location and logs ride details to the database.
  • Includes robust error handling and adherence to CORS policies.
  • Lambda function enables rapid, serverless deployment and is testable using JSON-based inputs.

About

This project involves building a full-stack web application for a fictional ride-sharing service, Wild Rydes, leveraging seven AWS services. Users can create accounts, log in, and request rides by selecting locations on a map powered by ArcGIS.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages