Getting started with AWS.
How to build RESTful API



Dzmitry Tsebruk
Junoir Software Engineer

AWS
Junior Developer
What is FaaS?


AWS Overview


Lambda





Cold and Warm start
How to write Lambda Function?
exports.handler = (event, context, callback) => {
https.get(url, (res) => {
callback(null, res.statusCode)
}).on('error', (e) => {
callback(Error(e))
})
}
exports.handler = async (event) => {
return new Promise((resolve, reject) => {
if (Math.random() * 2 ^ 0) {
resolve();
} else {
reject();
}
});
}
or
exports.handler = async (event) => {
return https.get(url).promise();
}
or
Livecoding
IAM

Livecoding
API Gateway

Livecoding
Ways to manage AWS
AWS CLI usage example
# aws lambda invoke \
--function-name <value> \
<outfile>
Livecoding
Terminal
AWS SDK usage example
var lambda = new AWS.Lambda();
lambda.addLayerVersionPermission(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
var lambda = new AWS.Lambda();
lambda.addLayerVersionPermission(params).promise();
or
Database Services

Livecoding
AWS Free Tier
Free Tier Details
Billing Dashboard

Billing Dashboard

Pros & Cons
Pros
- Cheap cost
- Auto scalable
- You can make simple things easily
Cons
- You should track what happens
- Сomplex architecture
- It's hard to make tests
- Steep learning curve
Serverless Framework
Install framework and setup credentials
# npm install -g serverless
serverless.yml
service: aws-rest-ful-api
custom:
tableName: 'table-notes-${self:provider.stage}'
dynamodb:
start:
migrate: true
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: us-east-1
environment:
NOTES_TABLE: ${self:custom.tableName}
serverless.yml
functions:
create:
handler: src/handler.create
events:
- http:
path: notes
method: post
cors: true
getAll:
handler: src/handler.getAll
events:
- http:
path: notes
method: get
cors: true
delete:
handler: src/handler.delete
events:
- http:
path: notes/{id}
method: delete
cors: true
...
serverless.yml
resources:
Resources:
NotesDynamoDBTable:
Type: 'AWS::DynamoDB::Table'
Properties:
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:custom.tableName}
serverless.yml
NotesDynamoDBIamPolicy:
Type: AWS::IAM::Policy
DependsOn: NotesDynamoDBTable
Properties:
PolicyName: lambda-dynamodb
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: arn:aws:dynamodb:*:*:table/${self:custom.tableName}
Roles:
- Ref: IamRoleLambdaExecution
How to build RESTful API
src/handler.js
const AWS = require('aws-sdk');
const uuidv1 = require('uuid/v1');
const message = require('./message');
const dynamoDb = new AWS.DynamoDB.DocumentClient();
const { NOTES_TABLE } = process.env;
module.exports.create = async (event) => {
...
};
module.exports.getOne = async (event) => {
...
};
module.exports.getAll = async () => {
...
};
module.exports.update = async (event) => {
...
};
module.exports.delete = async (event) => {
...
};
src/handler.js
module.exports.getOne = async (event) => {
const { id } = event.pathParameters;
const params = {
TableName: NOTES_TABLE,
Key: {
id,
},
};
return new Promise((resolve) => {
dynamoDb.get(params, (error, result) => {
if (error) {
global.console.log(error);
message(400, 'Could not get the note!', resolve);
}
if (result.Item) {
message(200, JSON.stringify(result.Item), resolve);
} else {
message(404, 'Note is not found', resolve);
}
});
});
};
src/message.js
module.exports = (statusCode, body, callback) => {
const message = {
statusCode,
body,
};
message.headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
};
if (statusCode !== 200) {
message.headers['Content-Type'] = 'text/plain';
}
callback(message);
};
Deploying
# serverless deploy
Deploying

Now we can use endpoints ...
Thank You!
Links
- https://github.com/mikhama
- https://github.com/mikhama/aws-rest-ful-api
- https://aws.amazon.com/free/
- https://console.aws.amazon.com/billing/home
- https://docs.aws.amazon.com/cli/latest/reference/
- https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/
- https://serverless.com/framework/docs/providers/aws/guide/quick-start/
- https://serverless.com/framework/docs/providers/aws/guide/credentials/
Q&A
AWS
By Dzmitry Tsebruk
AWS
- 269