Session 5 | Connecting a Front End to API Gateway and Lambda

Pets

Workshop: Connecting a Front End to API Gateway and Lambda

We'll combine what we've learned about S3 static sites, API Gateway endpoints, and Dynamo DB functions to create a front end that can communicate with our API Gateway and Lambda backend.


Setup

Download the static site files which will serve as our frontend.

Open the files in your text editor and look around, particularly at the app.js file. There are three places labeled YOUR ENDPOINT HERE that we'll edit as we create our API Gateway later in this workshop.

Use $ open index.html to open the site in your browser.


Setting Up Lambda Functions

Open the Lambda console and create three functions. We will use these functions for the backend integration of our API Gateway endpoints. We will be working entirely in the dashboard instead of pushing code up from the command line.

  • allPets: should return the body "viewing all pets" like { body: "Viewing all pets" } -- no need for a status code since API Gateway will handle that for us
  • onePet: should return the body "viewing one pet", similar to above
  • createPet: should return the body "created a pet", similar to above

Your function dashboard should show the three functions (disregard the runtime since it might be different for you):

Screenshot for pet functions

Creating your API Gateway and First Endpoint

  1. In the API Gateway console, create a new REST API Gateway with the name petRescue.
  2. Screenshot for API Gateway creation
  3. From the Actions menu, select Create Resource. Use /pets for the Resource Name and Resource Path, and make sure to check off Enable API Gateway CORS.
  4. Screenshot for API resource creation
  5. From the Actions menu, select Create Method. In the dropdown that appears, choose GET. Click the checkbox to save it.
  6. Select Lambda Function as the integration type, and start typing the name of your allPets function, which should populate in the list. If you don't see your function, check that you're using the correct region. Click save and confirm the popup.
  7. Screenshot for API resource creation
  8. Click Test on the left-hand side which will bring you to the test screen. Scroll down to the blue Test button and click it. You should see the output below:
  9. Screenshot for test result
  10. Even though this works in testing (and would work if were were to deploy right now and access the endpoint through the browser), the HTTP response for this GET request is mising the Access-Control-Allow-Origin header, so our outside site will not be able to get data from our API as of right now through JavaScript. Let's fix this by clicking on the GET method, then selecting Enable CORS from the Actions menu.
  11. Screenshot for test result
  12. Check off DEFAULT 4xx and DEFAULT 5xx and leave all other settings the same. Click the blue Enable CORS and replace existing CORS headers button. Confirm the popup.
  13. Screenshot for test result
  14. From the Actions menu, select Deploy API. Create a new v1 Deployment Stage and click Deploy.
  15. Screenshot for new deployment stage
  16. Copy your endpoint and paste it into the app.js file on line 6. Don't forget to add the /pets path on the end!
  17. Screenshot for API URL Screenshot for JS code
  18. Wait a minute or two, then refresh your index.html file in your browser and click on the Show All Pets button. It should say "Viewing all pets". Depending on how you set up your code, you may or may not see quote marks around the return value.
  19. Screenshot of website loading data

Creating an Endpoint with a Dynamic Path

In this section, we'll create the /pets/:id path. For now, we'll have our Lambda function just return the value of the path. In Session 6, we'll connect to a DynamoDB to retrieve actual values.

  1. In your API Gateway dashboard, click Resources under your petRescue API. Then click the Actions dropdown and click Create Resource.
  2. Screenshot showing how to create new resource
  3. Enter {id} for both the Resource Name and Resource Path. Check Enable CORS Gateway.
  4. Screenshot showing dynamic path
  5. From the Actions menu, select Create Method. In the dropdown that appears, choose GET. Click the checkbox to save it. (This is identical to Step 3 from above, just with a different path.)
  6. If you're confused about how to do this step, go look at the screenshots from the first time you did this.

  7. Select Lambda Function as the integration type, and start typing the name of your onePet function, which should populate in the list. Click save and confirm the popup.
  8. Screenshot showing dynamic path
  9. We'll need to send the dynamic portion of the path to our Lambda function, so we're going to use a Mapping Template in the Integration Request. Click on Integration Request.
  10. Screenshot showing integration request
  11. Scroll to Mapping Templates and click on the arrow. Select "When there are no templates defined", add a mapping template for "application/json", and click the checkmark.
  12. Screenshot setting up mapping template
  13. In the textbox at the bottom, enter { "id": "$input.params('id')" }. This will send a JSON object that has a key of id and a value of the dynamic :id portion of the path from the parameters. Click save. It will look like nothing happened, but it saved :)
  14. Screenshot setting up mapping template
  15. Scroll up and click on the backward arrow to go back to Method Execution.
  16. Screenshot getting back to method execution
  17. Click on test. This time, enter a number in the {id} path param for the test.
  18. Screenshot entering number for path param
  19. Run the test. You should see Viewing one pet come back, but our Lambda function isn't doing anything with the data we're passing in.
  20. Open up the Lambda dashboard in a new tab and go to your onePet function. Can you modify it so that you're using the id key of the event to print out a message that says "Viewing one pet: 7" (or whatever number gets passed in)? Hint: the id is coming from the event parameter...
  21. Once you've fixed and saved your Lambda function code, go back to API Gateway and run your test again. This is the output you should get.
  22. Screenshot testing API gateway
  23. Enable CORS for this path by selecting Enable CORS from the Actions dropdown.
  24. Screenshot enabling cors
  25. Check off DEFAULT 4xx and DEFAULT 5xx and leave all other settings the same. Click the blue Enable CORS and replace existing CORS headers button. Confirm the popup.
  26. If you're confused about how to do this step, go look at the screenshots from the first time you did this.

  27. From the Actions menu, select Deploy API. Select your v1 deployment stage and click Deploy.
  28. Copy your endpoint and paste it into the app.js file on line 16. Don't forget to keep the /pets/${id} path on the end!
  29. Screenshot for API URL Screenshot for inserting URL in JS code
  30. Wait a minute or two, then refresh your index.html file in your browser. Enter a number in the Pet number box and click on the Get pet button. It should say "Viewing one pet: 4" (or whatever number you entered).
  31. Screenshot of succesful one pet request

Creating a POST Endpoint to Send Data

In this section, we'll add a POST method to the /pets. For now, we'll have our Lambda function just return the value of the pet name we enter. In Session 6, we'll connect to a DynamoDB to retrieve actual values.

  1. Make sure you're in the Resources section of your API (not the Stages section).
  2. Under the /pets path, add a POST method by selecting Add Method from the Actions dropdown. Make sure to click the checkmark to save it.
  3. Screenshot for selecting post method
  4. Select your Lambda function createPet and click Save.
  5. Screenshot for selecting Lambda function
  6. Click on Test and scroll down to where you see the Request Body textbox. Switch over to your text editor and look at how our app.js file is sending the fetch request. The body is an object with keys name and id. We'll need to do the same thing when we set up our test body, using the structure { "name": "Joey", "id" : "7" }. Enter that in the textbox, then click Test.
  7. Screenshot for js code Screenshot for test body
  8. This is what you should see for the test output:
  9. Screenshot for test body
  10. Like before, nothing is happening with the data we're passing in. We don't need to use Mapping Templates this time since the data is not coming out of the URL (it's coming from the body of the request, which is passed directly to Lambda). Open up the Lambda dashboard in a new tab and go to your createPet function. Can you modify it so that you're using the name and id keys of the event to print out a message that says "Created Joey with ID 7" (or whatever name and ID gets passed in)?
  11. Once you've fixed and saved your Lambda function code, go back to API Gateway and run your test again. This is the output you should get.
  12. Screenshot for successful pet creation
  13. Enable CORS again from the Actions dropdown so that this new POST request has the correct headers.
  14. Screenshot for enabling cors
  15. From the Actions menu, select Deploy API. Select your v1 deployment stage and click Deploy.
  16. Copy your endpoint and paste it into the app.js file on line 27. Don't forget to keep the /pets path on the end!
  17. Screenshot for API URL Screenshot for inserting URL in JS code
  18. Wait a minute or so, then refresh your index.html file in your browser. Enter a name in the Pet name and number in the Pet id box, then click on the Create pet button. It should say "Created Joey with ID 7" (or whatever number you entered). If this does NOT work, try re-enabling CORS and re-deploying.

Deploying the Front End on S3

  1. Open up the S3 console and click Create Bucket. Choose a name for your bucket, then click through the options and make sure to uncheck the Block all public access option.
  2. Upload all of your frontend files into the bucket.
  3. In the Permissions tab, paste in this bucket policy that allows public access of your objects. Make sure to insert the ARN for your own bucket where indicated and don't forget to add the /* at the end of your bucket ARN so that the bucket policy refers to objects, not the bucket.
  4. {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Allow public access for static website files",
                "Action": [
                    "s3:GetObject"
                ],
                "Effect": "Allow",
                "Resource": "arn:aws:s3:::testpetrescue/*",
                "Principal": "*"
            }
        ]
    }
  5. Click on the Properties tab and enable Static website hosting. Type index.html for the index document. We do not have an error document, so leave that field blank. Click save.
  6. Click Static website hosting again so that you can get the URL of your website. Try it out!