In the Choose an API type section, find REST API - Develop a REST API where you gain complete control over the request and response along with API management capabilities.
Click Build
Click OK
In the Create new API section, select New API
In the API name section, type iDevelop - Trip Search API
In the Description section, type Allows searching ở trips from/to cities
Click Create API
The API will be created, and have a root path element and nothing else.
Click Actions
Click Create Resource
In the New Child Resource page
In the Resource Name section, type trips
Check Enable API Gateway CORS
Click Create Resource
The /trips resource will be created. Click on the /trips link
Click Actions
Click Create Method
In the dropdown list that appears, select GET
Click the grey tick next to the dropdown list to commit the change.
In the Lambda Region section, select your Region
In the Lambda Function section, type idevelop and select idevelopTripSearchFull
Click Save
Click OK
When the method is created, you will see the Method Execution panel:
Click Test
Click Test
After a moment or two for the Lambda function to initialise and execute, you should see an output similar to this:
Click /trips
Click Actions
Click Enable CORS
Click Enable CORS and replace existing CORS headers
Click Yes, replace existing values
When each of the listed items have a green tick against them, you can move on to the next section. This will only take a moment.
Expose the /tripsfromcity RESTful API endpoint
The first path we exposed was quite simple - /trips gets all the trips in the system. But we know our source code implementation allows us to specify a filter to query for trips that originate from a particular city or have a particular destination, so we want to expose this functionality to our API consumers. First, we will expose the /tripsfromcity path.
In the Resources section, click /
Click Actions
Click Create Resource
In the Resource Name section, type tripsfromcity
Select Enable API Gateway CORS
Click Create Resource
Our call into the Lambda function requires a city parameter. We will follow the standard pattern for RESTful interfaces, and pass this parameter in as a URL parameter. Select /tripsfromcity
Click Actions
Click Create Resource
In the Resource Name section, type {city}
In the Resource Path section, delete the default and replace with {city}
Click Create Resource
Click /{city}
Click Actions
Click Create Method
In the dropdown list that appears, select GET
Click the grey tick next to the dropdown list to commit the change.
In the Lambda Region section, select your Region
In the Lambda Function section, type idevelop and select idevelopTripSearchFromCity
Click Save
Click OK
When the method is created, you will see the Method Execution panel. as before for the /trips resource. We can’t go ahead and test the API call just yet, because we need to transform the request through API Gateway so that the city parameter is passed through to the Lambda function correctly.
The devlounge.lambda.FindTripsFromCityHandler handler expects to see the input data in this JSON format:
{
"payload" :
{
"city": "Melbourne"
}
}
This would cause the Lambda function to search DynamoDB for all trips that originate from Melbourne. We need to add a Body Mapping Template for this method in API Gateway to correctly transform the request into this format.
Click Integration Request
Click Mapping Templates
Click When there are no templates defined (recommended)
Click Add mapping template
In the Content-Type section , type application/json
Click the grey tick icon to commit the change.
Scroll further down to show the mapping template entry text field. Paste in the following template:
This template will take the parameter {city} from the URL and add it into a JSON payload that is sent to the Lambda function, as a property of the payload object, just as the Lambda function expects.
Click Save
The schema defined here for this Lambda function is completely arbitrary, and in your own application you could use a completely different model. The mapping template gives you the flexibility to transform the inbound data on-the-fly through the API Gateway endpoint.
Click Method Execution
Click Test
In the Path section, in {city} field, type Melbourne
Click Test
API Gateway will make the call into the Lambda function, passing the value Melbourne into the Body Mapping Template you have defined, which will insert the search parameter Melbourne into the JSON payload that is sent to the Lambda function. This will cause the function handler to consume the JSON and execute a search in the DynamoDB table, and return the results. You will see a result similar to this:
Select /{city} in /tripsfromcity section
Click Actions
Click Enable CORS
Click Enable CORS and replace existing CORS headers
Click Yes, replace existing values
When each of the listed items have a green tick against them, you can move on to the next section. This will only take a moment.
Click / in Resources section
Click Actions
Click Create Resource
In the Resource Name section, type tripstocity
Select Enable API Gateway CORS
Click Create Resource
Our call into the Lambda function requires a city parameter. We will follow the standard pattern for RESTful interfaces, and pass this parameter in as a URL parameter. Click /tripstocity
Click Actions
Click Create Resource
In the Resource Name section, type {city}
In the Resource Path section, delete the default and replace with {city}
Select Enable API Gateway CORS
Click Create Resource
Click /{city} in the section /tripstocity
Click Actions
Click Create Method
In the dropdown list that appears, select GET
Click the grey tick next to the dropdown list to commit the change.
In the Lambda Region section, select your Region
In the Lambda Function section, type idevelop and select idevelopTripSearchToCity
Click Save
Click OK
When the method is created, you will see the Method Execution panel, as before for the /tripsfromcity resource. We again need to transform the request through API Gateway so that the city parameter is passed through to the Lambda function correctly, before we can test this API call.
The devlounge.lambda.FindTripsToCityHandler handler expects to see the input data in this JSON format:
{
"payload" :
{
"city": "Melbourne"
}
}
This would cause the Lambda function to search DynamoDB for all trips that have Melbourne as a destination. We need to add a Mapping Template for this method in API Gateway to correctly transform the request into this format.
Click Integration Request
Click Mapping Templates
Select When there are no templates defined (recommended)
Click Add mapping template
In the Content-Type section, type application/json
Click the grey tick to commit the change
Scroll further down to show the mapping template entry text field. Paste in the following template:
In the Path section, in the {city} field, type Melbourne
Click Test
API Gateway will make the call into the Lambda function, passing the value Melbourne into the Body Mapping Template you have defined, which will insert the search parameter Melbourne into the JSON payload that is sent to the Lambda function. This will cause the function handler to consume the JSON and execute a search in the DynamoDB table, and return the results. You will see a result similar to this:
Click /{city} in /tripstocity section
Click Actions
Click Enable CORS
Click Enable CORS and replace existing CORS headers
Click Yes, replace existing values
When each of the listed items have a green tick against them, you can move on to the next section. This will only take a moment.
If you have completed the steps above as described, you will have a resources tree that looks like this:
Deploy the API and test
Now that you have confirmed that the microservices are functioning correctly, you are ready to deploy the API and test it from the publicly available endpoint. In the Resources section, click /
Click Actions
Click Deploy API
In the Deployment stage section, select [New Stage] to create a new deployment stage.
In the Stage name section, type prod
In the Stage description section, type Trips API
In the Deployment description section, type Initial deployment
Click Deploy
The new stage prod will be created and you will see the prod Stage Editor
Click Invoke URL
A new window will open and hit the stage endpoint. You will see an error message stating {“message”:“Missing Authentication Token”}. This is because there is no handler for the root of the stage - you have only defined resources/methods beneath the /trips, /tripsfromcity and /tripstocitypaths.
Edit the URL in the URL bar of the browser and append /trips then press Enter. The page will refresh, and then display all of the available trips as JSON. The output will be similar to this:
Test the /tripsfromcity method, use /tripsfromcity/Melbourne to search for all trips that leave from Melbourne.
Test the /tripstocity method, use /tripstocity/Melbourne to search for all trips that go to Melbourne.
NIf the data looks right, and there are no errors, you are ready to move on to the next exercise.
Use CloudFormation/SAM via the AWS CLI to deploy the HotelSearch microservice
In the previous steps, you manually deployed and configured the TripSearch microservice, including the Lambda functions and API Gateway resources. You will have noticed that there are quite a few steps required, and doing this manually is time consuming and prone to errors. In this step, you will use the AWS CLI and CloudFormation/SAM to deploy the HotelSearch microservice, instead of manually deploying the resources.
By using CloudFormation/SAM, many of the manual steps will be taken care of for you, streamlining the deployment process. You will still have to manually trigger the process, but the actual deployment will be automated.
The HotelSpecials microservice needs to access a MySQL database to retrieve the hotel specials data. The lab environment has automatically deployed and seeded a database for you, and the connection details are provided in Cloudformation Outputs tab with instructions below on where to update the placeholder in the template you will use to deploy the microservice. The MySQL instance has been deployed using Amazon RDS and is not publicly-accessible since it is launched in a private subnet. Therefore, for the Lambda function to be able to connect to the database, the Lambda function will also need to be deployed into a private subnet by enabling VPC Integration. The template.yml file provided has all the required setup to do this, you just need to update the placeholders as per the below instructions.
Open Command Prompt and navigate to the directory of the HotelSpecials project was extracted in step 65
Execute the following command:
set AWS_PROFILE=devaxacademy
mvn package shade:shade
67. When the target JAR is built, whick is in the target folder of the project and whose name is hotelspecials-1.0.0.jar
68. Go to AWS CloudFormation Console.
Click Stack.
Type DevAx-06 to the search bar and press Enter.
Click DevAx-06.
Click tab Output
Save the value of DatabaseSecurityGroup, DatabaseSubnet1, DatabaseSubnet2, RDSEndpoint and S3BucketLambdaCodeBucketName to use in the next step.
In the Eclipse IDE, open the template.yml file
Replace <DatabaseSecurityGroup> by the DatabaseSecurityGroup value we saved in step 69
Replace <DatabaseSubnet1> by the DatabaseSubnet1 value we saved in step 69
Replace <DatabaseSubnet2> by the DatabaseSubnet2 value we saved in step 69
Replace <RDSEndpoint> by the RDSEndpoint value we saved in step 69
Save
In the Command Prompt, execute the following command to package the Lambda function
Replace <S3BucketLambdaCodeBucketName> by the S3BucketLambdaCodeBucketName value we saved in step 69
The command will upload the build artefact to the S3 bucket, and then update the template.yml pointer to the code artefact on S3, and write out a new template with this update included, to a file called template-export.yml
It will take a moment or two for the upload of the artefact to complete.
73. Execute the following command to create and deploy a CloudFormation Change Set
You will see the HotelSpecialsAPI stack. This indicates that the CloudFormation Change Set has been created. The command you issued will create the Change Set and then automatically execute the Change Set. It will take a few moments to complete the execution
Select HotelSpecialsAPI stack, click tab Events and eview the steps that the CloudFormation template has applied to your environment. These will match the resources and actions in the template-output.yml file.
The Integration Request panel will be shown. Lambda Function specified:
The specified value is not a Lambda function, but instead, is a Stage Variable that will be replaced at runtime by API Gateway. Therefore, in order for this API call to succeed, the Stage in API Gateway must have defined a value for the envHotelSpecials stage variable.
Click Stages
Click prod
Click tab Stage Variables
a single variable is defined - envHotelSpecials - which correlates to the stage variable name the GET method was expecting. The value of the variable is GetHotelSpecials which is the name of the Lambda function that the template created using the JAR file you built and uploaded during the package/deploy process.
Test the HotelSpecials API
Expand the prod root element in the Stages list to reveal the hierarchy.
Click Get
Click Invoke URL
After a moment while the Lambda function is initialised, you should see the JSON result of querying the mySQL database from the Lambda function
If you see a JSON payload with no errors, you have successfully deployed an API and supporting Lambda function that queries the mySQL database. Notice how much quicker and easier that was to deploy without any manual intervention? That is the power of automation. In the next exercise, we will take this one step further, using the (now familiar) CI/CD pipeline approach to deploy our next API.