Build a Secure Database Driven Web Application with Amplify and React: Part 2 - Add the Backend
In Part 1, we have built and deployed a secure serverless application to the web. It's functionality ist just quite limited without a backend. So let's change this. Start adding the backend with
> amplify add api
The command is interactive and asks for the following options:
- API Type REST
- Give it a descriptive name (in our case ardemo like the application will do)
- The path is the path to the resource and should get its name, for example
/customers/{id}
ID in curly brackets serves as a path parameter - Programming language: Python
- We do not need advanced options at this moment
- Restrict the API to authenticated users and open it to all operations
Amplify will create a folder and file structure under the projec/amplify folder. The created lambda function resides in the file /src/index.py:
import json
def handler(event, context):
print('received event:')
print(event)
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': json.dumps('Hello from your new Amplify Python lambda!')
}
This happens all locally on our development machine. You may guess, with amplify push, we can move it to the cloud and try it out. This is true but in reality it's even better. We can mock our function locally without the need of a cloud deployment! Imagine the backend is rather complex with sophisticated database queries. A developer likely has to make a few iterations with trying out to get this ready. The local mock will make this process faster and more efficient.
Test the function through Mock
To mock this initial function, enter
> amplify mock function
Confirm the next prompt, then the output will look like this:
Invoke Path and Query Parameters
Where is this received event 'test...' coming from? It comes from the event.json file in the src folder. By that, we can prepare a mock test case with any kind of request payload and parameters.Let's try this and change the event.json to something like this:
{ "httpMethod": "GET",
"path": "/customers",
"queryStringParameters": {
"name": "Mike"
},
"pathParameters": {
"id": 1
}
}
We have added an http method, a resource path and two parameters, one path parameter "ID" that we defined for our API earlier and a typical query string parameter. We can take advantage of those in the Python event handler:
import json
def handler(event, context):
print('received event:')
print(event)
id = event["pathParameters"]["id"]
name = event["queryStringParameters"]["name"]
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': json.dumps('This is a request for a resource named {0} with id {1}'
.format(name, id)
)
}
A new mock call will recognize the parameters and process them:
Here's the live demo of the steps so far:
Push the API to the Cloud
To see how the API works from the cloud, issue
> amplify push
The CLI will automatically recognize the deployed and yet undeployed components, create a CloudFormation stack and create and update the resources in the cloud. After a few minutes, a success message will appear, including the new REST API endpoint:
To test this, there are some limits we are facing. We have created a secured API with restricted access. Before we try to supply a valid request token, I would recommend to test with a tool that supports authorization with AWS credentials. Such a tool (and the only one I am aware of right now) would be Postman.
The required credentials are the AWS Access Key ID and Secret Access Key. They were required and downloaded to configure the Amplify CLI (and possibly other CLIs). So we can pull that .csv file up to get the values or create a new set from the AWS web console.
Best practice is to create an environment in Postman and store the credentials als variables:
A GET request using the created endpoint (given in the console output) and the authorization of type AWS Signature delivers the expected result that we already got by the local mock:
Keep in mind, the created Lambda function becomes accessible from the web via API Gateway. Thus, Amplify creates for our backend not only the Lambda function but also an API Gateway instance that contains as most important properties the path definition that we provided and the given permissions for the API operations (like GET). To find the deployed API, the best way is in consequence to look it up under API Gateway in the AWS Web Console. Under the selected API, there will be a decent diagram, showing the mentioned properties (the Lambda function on the right) and the request flow:
That's it! We have a secure serverless API deployed to the cloud and are able to test it locally and via the web. Next obvious step will be to connect the API to a database.
Comments
Post a Comment