{"id":27200952,"url":"https://github.com/julien-muke/powerofmath","last_synced_at":"2026-02-07T17:04:21.336Z","repository":{"id":210364168,"uuid":"726384603","full_name":"julien-muke/powerofmath","owner":"julien-muke","description":"AWS Project - Architect and Build an End-to-End AWS Web Application from Scratch.","archived":false,"fork":false,"pushed_at":"2023-12-05T15:14:56.000Z","size":3483,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-11T18:46:21.188Z","etag":null,"topics":["amazon-api-gateway","amazon-dynamodb","aws-amplify","aws-iam","aws-lambda"],"latest_commit_sha":null,"homepage":"https://dev.dov7jejtaezo6.amplifyapp.com/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/julien-muke.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-02T08:25:02.000Z","updated_at":"2023-12-02T14:27:21.000Z","dependencies_parsed_at":"2025-04-09T21:46:03.533Z","dependency_job_id":"be59e335-2121-4c0e-8cf3-817eafaf9d55","html_url":"https://github.com/julien-muke/powerofmath","commit_stats":null,"previous_names":["julien-muke/powerofmath"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/julien-muke/powerofmath","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julien-muke%2Fpowerofmath","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julien-muke%2Fpowerofmath/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julien-muke%2Fpowerofmath/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julien-muke%2Fpowerofmath/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/julien-muke","download_url":"https://codeload.github.com/julien-muke/powerofmath/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julien-muke%2Fpowerofmath/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29200843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T16:28:23.579Z","status":"ssl_error","status_checked_at":"2026-02-07T16:28:22.566Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amazon-api-gateway","amazon-dynamodb","aws-amplify","aws-iam","aws-lambda"],"created_at":"2025-04-09T21:45:58.856Z","updated_at":"2026-02-07T17:04:21.312Z","avatar_url":"https://github.com/julien-muke.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"## AWS Project - Architect and Build an End-to-End AWS Web Application\nIn this hands-on project, I’ll walk you through how to design and build a simple web application from scratch.  We’ll pick five different services—Amplify, Lambda, IAM, API Gateway and DynamoDB—and talk about why/where to use them, and how to get them to work with each other.  As we go, we’ll build out each of the services, resulting in a fully-functional math web application.\n\n## The Application Architecture\n\n![Screenshot](/images/app_archi.png)\n\n\n![Screenshot](/images/img_1.png)\n\n### [🌐 LIVE SITE](https://dev.dov7jejtaezo6.amplifyapp.com/)\n\n\nWhat do we need?\n\n- A way to create/host a webpage\n- A way to involke the math functionality\n- A way to do some math\n- Somewhere to store/return the math result\n- A way to handle permissions\n\n## Step 1: Create an index.html page from scratch in a text editor\nOpen your text editor, create an index.html file and paste the code below:\n\n ```bash\n        \u003c!DOCTYPE html\u003e\n        \u003chtml\u003e\n            \u003chead\u003e\n                \u003cmeta charset=\"UTF-8\"\u003e\n                \u003ctitle\u003eTo the Power of Math!\u003c/title\u003e\n            \u003c/head\u003e\n\n            \u003cbody\u003e\n                To the Power of Math!\n            \u003c/body\u003e\n        \u003c/html\u003e\n\n   ```\n\n## Step 2: Deploying and hosting a web page with AWS Amplify\nwhat we need to do is zip just the index.html file, now we're going to use amplify to deploy it.\n\nIn the aws console navigate to  amplify, click Get Started on Amplify Hosting:\n\n![Screenshot](/images/img_2.png)\n\nSelect Deploy without Git Provider:\n\n![Screenshot](/images/img_3.png)\n\nGive the app a name, i'm going to call mine \"power of math\", the environment name i'm going to use \"dev\" and we want to drag and drop that zip file that we created:\n\n![Screenshot](/images/img_4.png)\n\nSave and deploy, after the deployement is successfully completed, you can access the link under Domain, open it on a new tab, we now have a live web page that users can navigate to:\n\n![Screenshot](/images/img_5.png)\n\n## Step 3: Creating a Python Lambda function to implement our math functionality\nwe're going to use a lambda function as you might know a lambdafunction is just a bit of code that runs in response to some trigger for example when you upload a picture to an s3 bucket that could trigger a lambda function to go process the picture into a thumbnail or something like that it's just code or functions really sitting out there that get run when you need them and these are serverless meaning that you don't have to set up and manage servers to run the code it just happens automatically behind the scenes for you\nso we'll write some python code and use the python math library to do the calculations that we need.\n\nBack here on the console go ahead and open up new tab this time we're going to navigate to lambda, create a funtion:\n\n![Screenshot](/images/img_6.png)\n\nThen for function name i'm going to do \"power of math function\", in my case for runtime let's go with the latest version of python 3.11 , you can leave everything else the same and create function down here on the lower right:\n\n![Screenshot](/images/img_7.png)\n\n\nFom the Code Source section, copy and replace the lambda function code provided below: \n\n ```bash\n      # import the JSON utility package\n        import json\n        # import the Python math library\n        import math\n\n        # define the handler function that the Lambda service will use an entry point\n        def lambda_handler(event, context):\n\n        # extract the two numbers from the Lambda service's event object\n        mathResult = math.pow(int(event['base']), int(event['exponent']))\n\n        # return a properly formatted JSON object\n        return {\n        'statusCode': 200,\n        'body': json.dumps('Your result is ' + str(mathResult))\n        }\n\n   ```\n\n\n   Replace and paste the lambda function code, save the changes and make sure to deploy by cliking the deploy button:\n\n   ![Screenshot](/images/img_8.png)\n\n\n## Step 4: Testing our Lambda function\nlet's test to make sure this functions work as we expect, click the little drop down arrow to the\nright of test: \n\n![Screenshot](/images/img_9.png)\n\nSet up a test event this basically lets us pass in some test data to make sure that the function's working, create a new event event name power of math test event, we only have two values to pass in one of them is going to be base and one is going to be exponent and you can choose whatever values you want here i'm going to do 2 to the power of 3, the clik the save button:\n\n![Screenshot](/images/img_10.png)\n\nRun the test by cliking the test button, the base value of 2 to the power of 3 should give us 8 as a result:\n\n![Screenshot](/images/img_11.png)\n\n## Step 5: How to invoke our Lambda function\nThe way to invoke that math functionality or basically invoke that lambda function so our users obviously aren't going to go into the aws console like we just did and run it so we need a public endpoint or url that can be called to trigger that function to run and for that we're going to use api gateway this is a core service in aws that you can use to build your own apis application programming interfaces whether those are http rest or websocket APIs and it's really the perfect way to\ninvoke a lambda function.\n\nTo Creating a REST API for our Lambda function using API Gateway, on console navigate the API Gateway, create a new one by clicking on the create api button, we're going to use REST API, so click build button:\n\n![Screenshot](/images/img_12.png)\n\n\nLeave these first two options as they are so this will be rest and a new api and then we need to give it a name\nso mine will be \"power of math api\". you can leave everything else the same and then create api :\n\n![Screenshot](/images/img_13.png)\n\nFor the API method to be called, on the left make sure you have resources selected and then make sure you've got the backslash selected and then create method:\n\n\n![Screenshot](/images/img_14.png)\n\n\nThe type of method will be a post and for integration type we're going to use a lambda function and then the lambda function name itself you'll need to start typing it should be power of math function, click on create method:\n\n![Screenshot](/images/img_15.png)\n\n\nOne other thing we need to do is enable CORS or Cross Origin Resource sharing:\n\n\n![Screenshot](/images/img_16.png)\n\n\nBasically what this does is allows a web application running in one origin or domain to be able to access resources on a different origin or domain, because our web application is running on one domain and amplify our lambda function is going to be running in another we need to be able to work across those domains or origins, clik save:\n\n\n![Screenshot](/images/img_17.png)\n\n\nLet's deploy the api so we can test it out:  \n\n\n![Screenshot](/images/img_18.png)\n\n\nWe'll need to set up a new stage you might have different stages for dev test production and so on this one we'll call dev and deploy:\n\n\n![Screenshot](/images/img_19.png)\n\n\nYou'll need to copy the invoke url on a notepad and we'll need that for later:\n\n\n![Screenshot](/images/img_20.png)\n\n## Step 5: Creating a new DynamoDB table to store our math result\n\nwe're going to be using DynamoDB this is a key value or NOSQL database it's generally going to be\nlighter weight than something like a relational database where you have to go set up your schema your relationships and we have to deal with permissions as well specifically we're going to need to give our lambda function permission to write to the database so let's go work on this next.\n\nOn the console navigate to DynamoDB, create table: \n\n\n![Screenshot](/images/img_21.png)\n\n\nWe want to create table for table name i'll do \"power of math database\", for partition key we'll say ID\nyou can leave everything else the same and create table: \n\n\n![Screenshot](/images/img_22.png)\n\n\nWe do need to save the Amazon Resource Name or the ARN for this so if you click into that table and under general information and additional info grab the ARN, and then just paste that into the same notepad or whatever you're using to store your links, and we'll come back and get that later: \n\n\n![Screenshot](/images/img_23.png)\n\n\n## Step 6: Giving Lambda permission to write to the DynamoDB table\n\nNavigate back to lambda and find the function and you want to go to the configuration tab (IAM)\nand then if it's not already selected go to permissions and then you want to click on role\nname, the execution role this should open up in a new tab and we basically need to add some\nadditional permissions to what this role has already permissions related to dynamodb:\n\n\n![Screenshot](/images/img_24.png)\n\n\nAdd permissions and create inline policy, i personally find it easier just to work with the json code so click on the json tab and grab this code:\n\n\n ```bash\n        {\n        \"Version\": \"2012-10-17\",\n        \"Statement\": [\n            {\n                \"Sid\": \"VisualEditor0\",\n                \"Effect\": \"Allow\",\n                \"Action\": [\n                    \"dynamodb:PutItem\",\n                    \"dynamodb:DeleteItem\",\n                    \"dynamodb:GetItem\",\n                    \"dynamodb:Scan\",\n                    \"dynamodb:Query\",\n                    \"dynamodb:UpdateItem\"\n                ],\n                \"Resource\": \"YOUR-TABLE-ARN\"\n            }\n            ]\n        }\n\n```\n\n\nCopy all of this and replace what i have here and this is just basically saying allow\nall these different actions in dynamodb so the lambda function is going to have\npermissions to do all of these things on our dynamodb table.\n\n\nYou need to update this right here to that table arn that you copied just a minute, starting with ARN  ```bash YOUR-TABLE-ARN``` so copy that paste it: \n\n\n![Screenshot](/images/img_25.png)\n\n\nThen we'll review policy, we'll give it a name \"power of math dynamo policy\" and finally create policy on the lower right:\n\n\n![Screenshot](/images/img_26.png)\n\n\n\n## Step 7: Updating the Lambda function code to write to the DynamoDB table\n\nUpdate the lambda function to actually go right to the database it wasn't doing\nthat before so let's come back to the lambda function, copy and replace the code:\n\n\n ```bash\n    # import the JSON utility package\n        import json\n        # import the Python math library\n        import math\n\n        # import the AWS SDK (for Python the package name is boto3)\n        import boto3\n        # import two packages to help us with dates and date formatting\n        from time import gmtime, strftime\n\n        # create a DynamoDB object using the AWS SDK\n        dynamodb = boto3.resource('dynamodb')\n        # use the DynamoDB object to select our table\n        table = dynamodb.Table('PowerOfMathDatabase')\n        # store the current time in a human readable format in a variable\n        now = strftime(\"%a, %d %b %Y %H:%M:%S +0000\", gmtime())\n\n        # define the handler function that the Lambda service will use an entry point\n        def lambda_handler(event, context):\n\n        # extract the two numbers from the Lambda service's event object\n            mathResult = math.pow(int(event['base']), int(event['exponent']))\n\n        # write result and time to the DynamoDB table using the object we instantiated and save response in a variable\n            response = table.put_item(\n                Item={\n                    'ID': str(mathResult),\n                    'LatestGreetingTime':now\n                    })\n\n        # return a properly formatted JSON object\n            return {\n            'statusCode': 200,\n            'body': json.dumps('Your result is ' + str(mathResult))\n         }\n\n```\n\n\nUpdated code make sure you save with a control very importantly make sure you deploy this pushes out your changes\n\n\n![Screenshot](/images/img_27.png)\n\n\n## Step 8: Updating the index.html page to call API Gateway\n\nFor this part we're going to need to update the index.html page so go ahead and copy the code, you need to update your api gateway endpoint \"YOUR API GATEWAY ENDPOINT\" with your url you saved on your notepad, it should end in dev if you created a dev stage like i did: \n\n\n```bash\n    \u003c!DOCTYPE html\u003e\n        \u003chtml\u003e\n        \u003chead\u003e\n            \u003cmeta charset=\"UTF-8\"\u003e\n            \u003ctitle\u003eTo the Power of Math!\u003c/title\u003e\n            \u003c!-- Styling for the client UI --\u003e\n            \u003cstyle\u003e\n            h1 {\n                color: #FFFFFF;\n                font-family: system-ui;\n                margin-left: 20px;\n                }\n            body {\n                background-color: #222629;\n                }\n            label {\n                color: #86C232;\n                font-family: system-ui;\n                font-size: 20px;\n                margin-left: 20px;\n                margin-top: 20px;\n                }\n            button {\n                background-color: #86C232;\n                border-color: #86C232;\n                color: #FFFFFF;\n                font-family: system-ui;\n                font-size: 20px;\n                font-weight: bold;\n                margin-left: 30px;\n                margin-top: 20px;\n                width: 140px;\n                }\n            input {\n                color: #222629;\n                font-family: system-ui;\n                font-size: 20px;\n                margin-left: 10px;\n                margin-top: 20px;\n                width: 100px;\n                }\n            \u003c/style\u003e\n            \u003cscript\u003e\n                // callAPI function that takes the base and exponent numbers as parameters\n                var callAPI = (base,exponent)=\u003e{\n                    // instantiate a headers object\n                    var myHeaders = new Headers();\n                    // add content type header to object\n                    myHeaders.append(\"Content-Type\", \"application/json\");\n                    // using built in JSON utility package turn object to string and store in a variable\n                    var raw = JSON.stringify({\"base\":base,\"exponent\":exponent});\n                    // create a JSON object with parameters for API call and store in a variable\n                    var requestOptions = {\n                        method: 'POST',\n                        headers: myHeaders,\n                        body: raw,\n                        redirect: 'follow'\n                    };\n                    // make API call with parameters and use promises to get response\n                    fetch(\"YOUR API GATEWAY ENDPOINT\", requestOptions)\n                    .then(response =\u003e response.text())\n                    .then(result =\u003e alert(JSON.parse(result).body))\n                    .catch(error =\u003e console.log('error', error));\n                }\n            \u003c/script\u003e\n        \u003c/head\u003e\n        \u003cbody\u003e\n            \u003ch1\u003eTO THE POWER OF MATH!\u003c/h1\u003e\n            \u003cform\u003e\n                \u003clabel\u003eBase number:\u003c/label\u003e\n                \u003cinput type=\"text\" id=\"base\"\u003e\n                \u003clabel\u003e...to the power of:\u003c/label\u003e\n                \u003cinput type=\"text\" id=\"exponent\"\u003e\n                \u003c!-- set button onClick method to call function we defined passing input values as parameters --\u003e\n                \u003cbutton type=\"button\" onclick=\"callAPI(document.getElementById('base').value,document.getElementById('exponent').value)\"\u003eCALCULATE\u003c/button\u003e\n            \u003c/form\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e\n\n```\n\n\n## Step 9: Re-deploying our index.html page using Amplify\n\nMake a zip file out of this again so i'm going to delete our original zip file and then update index.html,compressed the file to a new zip and then we're going to need to go redeploy it using amplify, drag and drop the zip file to amplify, this will automatically redeploy.\n\n### [🌐 LIVE SITE](https://dev.dov7jejtaezo6.amplifyapp.com/)\n\n\n## Cost\nAll services used are eligible for the [AWS Free Tier](https://aws.amazon.com/free/).  However, charges will incur at some point so it's recommended that you shut down resources after completing this tutorial.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulien-muke%2Fpowerofmath","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjulien-muke%2Fpowerofmath","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulien-muke%2Fpowerofmath/lists"}