Analyzing the Ionic AWS Full-Stack Starter: Custom APIs
In the previous tutorials here and there, we analyzed the amazing Ionic AWS Full-Stack Starter project.
Accessing pre-built methods from AWS services like S3, Cognito or DynamoDB is super cool, but what do we do if we need some custom methods? Do we create another Node.js server on the side?
The answer is no!
We can directly create custom backend endpoints with AWS.
In this tutorial we will create an endpoint that will return the number of tasks present in the database and at the end we will use our Ionic AWS project to call it.
Roles
Let's start by setting up the Identity and Access Management (IAM) there.
Select the "Roles":
Create a new role:
Select AWS Lambda for type:
Add one permission to use DynamoDB:
And set the role's name:
Lambda Function
Now we need a lambda function there.
Select "Create a Lambda function":
Many starting templates there, but we will start from scratch and create a blank function:
We can now use our role:
A basic getTableLength function is now created.
Let's update this function:
exports.handler = (event, context, callback) => {
var responseCode = 200;
var responseBody = {
received: true
};
var response = {
statusCode: responseCode,
headers: {
"x-custom-header": "custom header value"
},
body: JSON.stringify(responseBody)
};
context.succeed(response);
};
We add everything we need to return a response to a client by setting up the response code, body and the response itself.
Nothing hard here.
The context object will be used to send the response by using the succeed method.
Great, we have a basic response ready to be used!
API
The final part is creating the API in the Amazon API Gateway there.
Name the API:
Create a new method:
And set the type to GET:
The aim now is to use the getTableLength Lambda Function from your region (mine is us-east-1):
We are now redirected to this cool screen:
The most important area is the upper part, especially:
- One click on this link leads to the lambda function edition screen
- The API can be tested there
Here is the result of a test that sends a GET Request:
The API is working as it should! This is only available in local, we need to expose it to the public.
A deployment is required:
A new Stage named Dev is created:
This Stage is generally used for development purposes.
Finally the service is available at this url:
What’s next?
The Ionic call! Back to our starter stack.
Back to the Ionic application
We head to the app.module.ts file to add the HttpModule:
import { HttpModule } from '@angular/http';
@NgModule({
.
.
.
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(MyApp, new AwsConfig().load())
],
.
.
.
})
From there you can go wherever you want, I’m going to make my test call in the tasks area, starting with the tasks.html file:
<ion-refresher (ionRefresh)="refreshData($event)">
<ion-refresher-content
pullingIcon="arrow-dropdown"
pullingText="Pull to refresh"
refreshingSpinner="circles"
refreshingText="Refreshing...">
</ion-refresher-content>
</ion-refresher>
<button ion-button color="danger" (click)="callBackEnd()">Call Custom REST API</button>
.
.
.
Just adding one button to make the call and moving to the tasks.ts file:
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
export class TasksPage {
.
.
.
constructor(..., public http: Http) {
.
.
.
}
The callBackEnd method:
callBackEnd() {
this.http.get('https://2nseea33n8.execute-api.us-east-1.amazonaws.com/Dev')
.map(res => res.json())
.subscribe(result => console.log('result: ', result));
}
And we are done!
Almost …
This error can pop:
‘member CORS?
Don’t worry, this can easily be handled in the API Gateway:
Ok now we are done!
We can now create any type of REST API in AWS.
Doing the work
Our final task is using DynamoDB in this API, more precisely in the Lambda Function.
At the top of our Lambda Function we add the following lines:
var AWS = require("aws-sdk");
var dynamo = new AWS.DynamoDB();
As you can see, AWS is available and every services are ready to be used.
The rest is very simple:
var params = {
TableName: 'ionic-mobile-hub-tasks'
};
dynamo.describeTable(params, function(err, data) {
if (err) {
console.log(err); // an error occurred
}
else {
console.log(data.Table.ItemCount);
var responseBody = {
received: true,
itemCount: data.Table.ItemCount
};
.
.
.
}
});
Setting up the params for the DynamoDB request, the ionic-mobile-hub-tasks table will be used.
The describeTable method will give us information about the table where our tasks are stocked.
If there are no errors, data.Table.ItemCount will give us the number of items, number that we add to the responseBody object.
When calling the updated API:
Our response is there!
Conclusion
If we know what we are doing, the whole process is simple. If not … it’s very easy to encounter many issues like the wrong roles, the wrong permissions, which url to call to access the endpoint and much more!
The whole process can be described as follow: Role -> Function -> API.
Take your time, and have everything correctly configured without skipping anything!