Setup an Amazon Api Gateway

Rohit Sharma
The Startup
Published in
9 min readJun 28, 2020

This article will talk about creating a Spring Boot microservices application, deploying it on an EC2 instance and then exposing the REST endpoints via the Api Gateway. Here’s the architecture we intend to achieve

Step 1: Lets begin by creating a spring boot app and dockerizing it

I’ve created a sample app. You’ll find the code here. It has its own version of an H2 database. You’ll find the dockerized version here . We’ll be deploying it to the EC2 instance.

Step 2: We’ll now create an EC2 instance

Since this is a very small application, we’ll choose the smallest instance available. The next set of images will walk you through the steps of creating the instance.

Choose the defaults on the rest of the settings

Now choose a key pair to connect to your instance or create a new one. Download it on your local machine.

You’ve now created an EC2 instance with a key pair to connect via ssh.

Step 3: Create an internal Network Load Balancer

The next set of images will show you how to create an NLB. Go to the Load Balancers section in the EC2 service and begin. This can be used to balance multiple EC2 intances

Make sure you select ‘internal’ in the settings below

Select availability in the zones that you need below.

You’ll now be able to see the load balancer like below.

Register you EC2 instance as a target as shown below. you can register multiple targets here.

Step 4: Create a VPC

A VPC is created by default when you create the EC2 instance. However, you can create your own if you want. We’ll be using the default vpc. you can see it on your VPC dashboard.

4 (a) — Now, create an endpoint service in your vpc

4 (b) — Add a whitelisted principle to the service

4 [c] — Add an endpoint connection to the service

Go to the endpoints section and create an endpoint

4 (d) — Add the endpoint to the endpoint service

Step 5: Deploy your application.

a. Login via ssh to your EC2 instance

ssh -i [your_key_pair_location] ec2-user@[ec2_instance_public_ip]

b. Get root access if required

sudo -s

c. Update your instance

yum update

d. Install docker

yum install docker

e. Start the docker service

service docker start

f. Pull the latest docker image

docker pull rohitsharma2311/testapi:latest

g. Run the image on docker.

docker run -p 80:8080 rohitsharma2311/testapi:latest

At the end of these steps, your spring boot app will be running on docker on the EC2 instance. You can also close all ports except the ssh port on your instance so that the endpoints are not directly accessible via http.

Step 6 : Create the API gateway.

For the last and final step, we’ll be creating the gateway. I’ll try and cover most of the features available to us. Follow these screenshots to create your gateway

a. Create the gateway

b. Create the VPC link

c. If you need an API key, go to API keys section from the left hand panel, and create one. If you’re asked for a stage in the following steps while adding the API key, then do these steps after creating the apis.

Create a usage plan and add the api key to the usage plan

d. We’ll now create a login endpoint. In this endpoint, we enter the user’s name and password and return a jwt token generated from it. You can add validations as per you need. For this, we’ll create a lambda and use this code. Now, lets create a /login endpoint. You can also ‘Create a Resource’ called ‘v1’ if you need versioning and then create a login resource within it.

Now create a ‘GET’ method within that resource to call the lambda.

Now, deploy the first version of you api. Go to ‘Actions’ and select ‘Deploy API’.

Choose a stage name (eg- ‘dev’, ‘qa’, ‘prod’) and then deploy the api.

Go to the ‘Stages’ section to find out the url for your api

You can now use this stage in the ‘Usage Plan’ section above to map you api key to this api.

You curl for the login api will look like this with the api version and api key needed to access it. (Go to EmployeeDataLoader.java in the code to add entities with multiple names. Currently, only ‘rohit’ is configured as a user.

curl — location — request GET ‘https://xxxxxxx.execute-api.us-east-1.amazonaws.com/{stage_name}/{api_version}/login' \
— header ‘x-api-key: xxxxxxxxxxxxxxx’ \
— header ‘Content-Type: application/json’ \
— data-raw ‘{
“username” : “rohit”,
“password” : “password”
}’

e. Create an ‘allowed’ endpoint under v1. This endpoint is available in my code and it needs the user name as the query param. We’ll use this endpoint in the authorizer lambda in the next step. This checks if the user name is an ‘admin’ and returns a success message to the authorizer lambda.

Remember to add {} in the resource path below.

The Get method will be linked to the vpc. Get your endpoint url from the endpoint you’d created before and then add /allowed/{name} to the string.

f. Now, create a lambda function using this code. Add this as an authorizer.

Here’s a diagram to explain how the lambda authorizer functions

g. Create a model that will be used to validate your input json to the POST call. Use the schema below(you can define your own)

{
“$schema”: “
http://json-schema.org/draft-07/schema",
“type”: “object”,
“required”: [
“id”,
“type”
],
“properties”: {
“id”: {
“type”: “integer”,
“minProperties”: 1
},
“type”: {
“type”: “string”,
“minProperties”: 1
},
“actor”: {
“type”: “object”,
“properties”: {
“id”: {
“type”: “integer”
},
“login”: {
“type”: “string”
},
“avatar_url”: {
“type”: “string”
}
}
},
“repo”: {
“type”: “object”,
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “string”
},
“url”: {
“type”: “string”
}
}
},
“created_at”: {
“type”: “string”
}
}
}

h. Lets create our POST endpoint. Create a new resource ‘events’. Create a POST method in it. Go to ‘Method Request’ section.

  1. Select the authorizer you created before in the ‘Authorization’ section.
  2. Select ‘Validate body’ in the ‘Request Validator’ section.
  3. Select ‘Api Key required’ as ‘true’.
  4. Add ‘tokenHeader’ and ‘x-api-key’ to the HTTP Request Headers section.
  5. Add the model you created in the ‘Request Body’ section.
  6. Save these changes and deploy the api.

Below is a sample curl

curl — location — request POST ‘https://xxxxxxx.execute-api.us-east-1.amazonaws.com/{stage_name}/{api_version}/events' \
— header ‘tokenHeader: {your_jwt_token}’ \
— header ‘x-api-key: {your_api_key}’ \
— header ‘Content-Type: application/json’ \
— data-raw ‘{
“id”:4151531141,
“type”:”PushEvent”,
“actor”:{
“id”:2790313,
“login”:”rohit23",
“avatar_url”:”https://avatars.com/123"
},
“repo”:{
“id”:352806,
“name”:”johnbolton/exercitationem”,
“url”:”https://github.com/"
},
“created_at”:”2020–10–02 06:13:31"
}’

i. Create a ‘GET’ method under /events. The only difference is that you’ll not add the mode. Everything else remains the same. Below is a sample curl

curl — location — request GET ‘https://xxxxxxx.execute-api.us-east-1.amazonaws.com/{stage_name}/{your_api_version}/events' \
— header ‘tokenHeader: {your_token_header}’ \
— header ‘x-api-key: {your_api_key}’

j. You can also add custom Responses for different http status codes. Edit a response from the list like shown below from the ‘Gateway Responses’ section.

Finally, go ahead and deploy your api to the same stage as before. Use the sample curls I’ve provided in the above sections to access your api. Make sure your spring boot app is running in the Docker instance.
You now have an api gateway setup where you’ve used most of the features it provides. Contact me if you have more questions.

--

--