Lab 6.1 - Developing REST APIs With Amazon API Gateway
Lab 6.1 - Developing REST APIs With Amazon API Gateway
In this lab, you will create a REST application programming interface (API) by using Amazon
API Gateway.
● Create simple mock endpoints for REST APIs and use them in your website.
● Enable Cross-Origin Resource Sharing (CORS)
Scenario
In the previous lab, you took on the role of Sofía to build a web application for the café. As
part of this process, you created an Amazon DynamoDB table that was named
FoodProducts, where you stored information about café menu items.
You then loaded data that was formatted in JavaScript Object Notation (JSON) into the
database table. The table structure looked similar to the following table (one line item of
table data is shown as an example):
In the previous lab you also configured code that used the AWS SDK for Python (Boto3) to:
● Scan a DynamoDB table to retrieve product details.
● Return a single item by product name using get-item as a proof of concept
● Create a Global Secondary Index (GSI) called special_GSI that you could use to
filter out menu items that are on offer and not out of stock.
In this lab, you will continue to play the role of Sofía. You will use Amazon API Gateway to
configure mock data endpoints. There are three that you will create:
Then in the lab that follows this one, you will replace the mock endpoints with real endpoints,
so that the web application can connect to the DynamoDB backend.
When you start the lab, the following resources are pre-created for you in the account.
However, by the end of this lab, you will have created the following architecture:
4. Arrange the AWS Management Console tab so that it displays along side these
instructions. Ideally, you will be able to see both browser tabs at the same time so
that you can follow the lab steps more easily.
Tip: If you want the lab instructions to display across the entire browser window, you
can hide the terminal in the browser panel. In the top-right area, clear the Terminal
check box.
5. From the AWS Management Console, connect to the AWS Cloud9 IDE named
Cloud9 Instance.
6. Download and extract the files that you will need for this lab.
○ In the same terminal, run the following command:
wget https://aws-tc-largeobjects.s3.us-west-2.amazonaws.com/CUR-TF-200-
ACCDEV-2/lab-04-api/code.zip -P /home/ec2-user/environment
○ Notice that a code.zip file was downloaded to the AWS Cloud9 instance. The
file is listed in the Environment window.
○ Extract the file:
unzip code.zip
○ Run the script that upgrades the versions of Python and the AWS CLI
installed in your IDE environment, and also creates the cafe website in your
AWS account.
The script will prompt you for the IP address by which your computer is
known to the internet.
Use www.whatismyip.com to discover this address and then paste the IPv4
address into the command prompt and finish running the script.
aws --version
○ Note: If you see a message about not using the latest version of pip, ignore
the message.
9. Verify that the cafe website can be loaded in a browser tab.
○ Load the website in a browser tab.
■ In a browser tab, open the Amazon S3 console.
■ Choose your bucket name, and then choose Objects.
If the files that the script just uploaded do not display, choose the
refresh icon to view them.
■ Choose the index.html file.
The first API resource will be called products. It will make a GET request so that the website
can retrieve all rows from the FoodProducts DynamoDB database table. You will then deploy
it in an API Gateway stage that's named prod. When a user visits the website, it will make an
AJAX request and return a list of café menu items from API gateway (it will return mock data
for now).
To complete all these tasks, you will use the SDK for Python.
11. In the AWS Cloud9 navigation pane, expand the python_3 directory and open the
file named create_products_api.py.
12. On line 3, replace the (fill me in) with the correct value that will create an API
Gateway client.
Tip: Consult the SDK for Python documentation as needed.
13. Take a moment to analyze the first part of what this code will do when you run it:
○ Lines 5-24 create a REST API that's named ProductsApi, and a resource
that's named products.
○ Lines 28-33 create a method request of type GET in the products resource.
You will analyze what the additional lines of code accomplish later in this task.
cd python_3
python create_products_api.py
15. Return to the AWS Management Console browser tab, and open the API Gateway
console.
16. Open the ProductsApi that you just created by choosing the link.
18. Take a moment to study the data flow in the GET method that you defined.
Tip: If you have a screen that is large enough, arrange the browser tabs so that you
have the AWS Cloud9 IDE open next to this browser tab. This way, you can see the
code and what it produced side-by-side.
○ On the left is the Client.
○ Lines 28-33 - When you run the Test, the Method Request is sent to the URL
in the Amazon Resource Name (ARN) detail. The request doesn't require any
authorization to invoke it.
○ Lines 50-58 - The Integration Request of type MOCK is invoked, and the
mock endpoint receives the data.
○ Lines 35-48 - The mock endpoint invokes the Integration Response, which
invokes the Method Response.
○ Lines 61-92 - The Method Response returns the REST API response back to
the Client that the request originated from.
Analysis: To make it easier during this initial API development phase, you will use
mock data. When you test the API call, it will not actually connect to the database.
Instead, it will return the data that's hardcoded in the responseTemplate part of the
code (lines 67-91).
This approach reduces the scope of potential errors during testing. You can stay
focused in this lab on ensuring that the REST API logic is well defined.
However, the structure of this mock data intentionally matches the data structure that
will appear in the next lab when Lambda will be interacting with the database table.
The key values will be mapped to the attributes that are defined in the DynamoDB
table (which you created in the previous lab).
Note: attributes in DynamoDB are not primatives. Instead, they are wrapper objects
(as shown in the example code below). This is why there is a slight difference
between the key names in the JSON and the attribute names in DynamoDB.
product_name: {
"S": "vanilla cupcake"
}
19. In the API Gateway console, choose the TEST link, then scroll to the bottom and
choose the Test button.
In the panel on the right, you should see the following response body, response
headers, and log information.
[
{
"product_name_str": "apple pie slice",
"product_id_str": "a444",
"price_in_cents_int": 595,
"description_str": "amazing taste",
"tag_str_arr": [
"pie slice",
"on offer"
],
"special_int": 1
},
{
"product_name_str": "chocolate cake slice",
"product_id_str": "a445",
"price_in_cents_int": 595,
"description_str": "chocolate heaven",
"tag_str_arr": [
"cake slice",
"on offer"
]
},
{
"product_name_str": "chocolate cake",
"product_id_str": "a446",
"price_in_cents_int": 4095,
"description_str": "chocolate heaven",
"tag_str_arr": [
"whole cake",
"on offer"
]
}
]
Congratulations! You have now successfully created and tested a REST API with a resource
that makes a GET request.
20. In the AWS Cloud9 navigation pane, expand the python_3 directory and open the
file named create_on_offer_api.py.
21. Replace <FMI_1> and <FMI_2> with the correct values so that this code file will add
another resource to the API that you defined in the previous task.
○ In a browser tab, go to the API Gateway console and choose the
ProductsApi API that you created a moment ago.
○ In the panel on the left, choose Resources.
○ Choose GET under products
○ In the breadcrumb navigation at the top of the screen (above the Actions
menu), you can see APIs > ProductsAPI followed by an id in parenthesis.
■ This is the api_id.
○ On the same line, you will see /products, followed by another id in
parenthesis.
■ This is the resource parent_id
[
{
"product_name_str": "apple pie slice",
"product_id_str": "a444",
"price_in_cents_int": 595,
"description_str": "amazing taste",
"tag_str_arr": [
"pie slice",
"on offer"
],
"special_int": 1
}
]
python create_on_offer_api.py
[
{
"product_name_str": "apple pie slice",
"product_id_str": "a444",
"price_in_cents_int": 595,
"description_str": "amazing taste",
"tag_str_arr": [
"pie slice",
"on offer"
],
"special_int": 1
}
]
Congratuations! You now have two API resources the website will be able to
use.
Task 4: Creating the third API endpoint (POST)
In this task, you will create a third resource for the API, /create_report. This resource
will be configured at the same level as /products (not as a nested resource under products).
Café staff who are logged in (authenticated) will later use this API resource to request an
inventory report.
The report details will be discussed in later labs. However, for now, you will configure the
API to support this feature. You will also test that the website can make an Asynchronous
JavaScript and XML (AJAX) request.
It is fully expected that the AJAX request will fail when you test it because you haven't
configured an authentication mechanism yet. However, you will configure authentication in a
later lab.
26. In the AWS Cloud9 IDE, if the create_products_api.py file is not already open, open
it (you ran this file in Task 2).
27. Next, in the python_3 directory, also open the create_report_api.py file.
28. In the main code editor window, right-click the create_report_api.py file tab and
choose Split Pane in Two Columns.
29. Analyze and update the create_report_api.py code. Be sure to compare the code in
this file to the create_products_api.py code while you do the analysis and updates.
○ Replace the <FMI_1> that appears on line 5 with the correct value.
Tip: You could use the console as you did before to discover the api_id.
However you can also use the AWS Command Line Interface (AWS CLI) to
find the value of the API ID by running the following command:
{
"msg_str": "report requested, check your phone shortly"
}
python create_report_api.py
31. In the API Gateway console, view the details of the report API that you configured.
○ Return to the API Gateway console tab and refresh the page.
○ Confirm that you are in ProductsApi.
○ In the navigation pane, confirm that Resources is selected, and choose
/create_report > POST.
You should see the details of the POST method execution.
32. Choose the TEST link, then choose the Test button at the bottom of the screen.
In the panel on the right, you should see the following response body, response
headers, and log information.
34. Copy the Invoke URL value to your clipboard. You will use it next.
window.COFFEE_CONFIG = {
API_GW_BASE_URL_STR: "https://<some-value>.execute-api.us-east-
1.amazonaws.com/prod",
COGNITO_LOGIN_BASE_URL_STR: null
};
○ Verify that prod appears at the end of the URL with no trailing slash.
○ Save the change to the file.
aws s3 ls
○ Notice that this script uploads the config.js file that you just editing the
previous step, and uploads it to the S3 bucket.
○ Save the change to the file, then run the script.
python update_config.py
37. Load the latest café webpage with the developer console view exposed.
○ If you still have the cafe website open in a browser tab, return to it. If you do
not still have it open, reopen it now by following these steps:
■ In the S3 console, choose the bucket that contains your website files.
■ Choose index.html and then copy the Object URL.
■ Load the Object URL in a new browser tab.
○ If you have not already done so, expose the developer console view in your
browser.
■ For example, if you are using Chrome, choose View > Developer >
View JavaScript Console
■ If you are using Firefox, choose Tools > Web Developer > Web
Console.
○ Now, refresh the browser tab to load the changes.
The Cafe website should display.
Note: if you have an issue loading the website, verify that you are still
connected to the internet from the same IP address that is hardcoded in the
bucket policy.
38. Test and observe details about the website and the application logic.
○ Scroll to the top of the Cafe website and choose login.
You will receive a message of "No API to call". This is expected. The
authentication logic will be implemented in a later lab. The generate report
call from the website will also be implemented in a later lab, from the
webpage that will load after a successful login.
○ Scroll down to the Browse Pastries section.
○ Notice that on offer is chosen by default.
Recall that at the beginning of this lab, you saw six product listings here.
However, now you should see only one product listing. That is because the
website is now displaying the mock data that you set in the
/products/on_offer resource you configured in Task 3.
○ Choose view all.
You should now see three products listed (these match the mock data you set
in the /products resource you configured in Task 2).
○ Observe the log messages printed to the developer console in your browser
tab.
■ The main.js file has logged that you are now using the API Gateway
to get either mock or real data.
■ Note: You may also see a message in the developer console that a
request to /bean_products has been blocked by CORS policy. You
can ignore this for now, since that is functionality that is introduced in
later labs.
○ Return to the Cloud9 IDE and open the resources/website/scripts/main.js file
details in the text editor.
■ Recall that at the start of this task, you set the
API_GW_BASE_URL_STR value in the config.js file to match the
Invoke URL value that was generated when you deployed the API.
■ Here in the main.js application code, you can observe how the Cafe
application logic notices that you are now using API Gateway to
retrieve menu data. So now, when the Cafe application loads menu
data, it calls the Invoke URL of the deployed API to retrieve it.
○ Congratulations! Your website is now making calls to the API that you created
and deployed.
After she successfully set up the website on Amazon S3, Sofía has been excited to improve
the website's functionality. Her larger plan is to build a serverless dynamic website with a
database backend. Sofía's plan has three major milestones.
● The first milestone was to create a database backend to store café data. She
accomplished that in the previous lab by using DynamoDB.
● The second milestone is to create a REST API so that the webpages that are hosted
on Amazon S3 can interact with the backend database. Sofía just completed the
most difficult part of that task during this lab.
The following diagram summarizes the features that Sofía has built in the last lab and
in this lab:
Though the API currently uses mock data, it should be straightforward to replace the mock
endpoints with actual endpoints that can communicate with the database.
● The third milestone will be accomplished in the next lab. Sofía will create AWS
Lambda functions. The REST API resources that she created in this lab will trigger
those Lambda functions to query the DynamoDB table. This database table contains
the actual data that she stored in the previous lab.
Finally, in later labs in the course, Sofía will use Amazon Cognito to implement the
authentication logic that the create_report API call expects.
Sofía knows that she has work to do. For now, though, Sofía decides to celebrate her most
recent accomplishment by relaxing with her friends.
Submitting your work
39. At the top of these instructions, choose Submit to record your progress and when
prompted, choose Yes.
Tip: If you previously hid the terminal in the browser panel, expose it again by
selecting the Terminal checkbox. This action will ensure that the lab instructions
remain visible after you choose Submit.
40. If the results don't display after a couple of minutes, return to the top of these
instructions and choose Grades
Tip: You can submit your work multiple times. After you change your work, choose
Submit again. Your last submission is what will be recorded for this lab.
41. To find detailed feedback on your work, choose Details followed by View
Submission Report.
Lab complete
Congratulations! You have completed the lab.
42. Choose End Lab at the top of this page, and then select Yes to confirm that you want
to end the lab.
A panel indicates that DELETE has been initiated... You may close this message box
now.