Serverless with AWS a simple introduction
Tags: serverless, aws, beginners, bettercode
Published: 2020-08-27 02:58:58

## What is serverless?
Serverless still means you’re using servers but you’re not provisioning and managing those servers yourself but instead these servers are running in the cloud provided by a provider like AWS, Azure, or Google Cloud. They dynamically allocate resources for executing a piece of code (function) and only charge for the number of resources being used to execute that code. Most of the time your code is being run inside a stateless container that can be triggered by events like an HTTP request, database events, file uploads, or CRON jobs. A stateless container means that you can’t rely on other functions executing before or after your own function, everything is done inside that one function in a new container every time. Everything will become a single little service (Microservice) which can also be called FaaS (Functions as a Service).

Some popular serverless technologies include Google’s firebase, some AWS services, some azure services, and serverless (https://www.serverless.com) where serverless isn’t necessarily a service in itself but a popular tool to develop, deploy and monitor serverless applications to cloud providers. This time we will be focusing on the AWS serverless services.

### Benefits of serverless:
- No need to set up servers yourself
- Inherently scalable
- May reduce costs since you only pay for what you use
- Quick deployments/updates are possible
- flexibility

### Drawbacks of serverless:
- Debugging can be a pain sometimes
- Vendor lock-in
- security issues
- It’s stateless and you can’t just build everything in serverless
- Integration testing is more difficult

## Cold starts
Every time a function is called a container is created on-demand and the function is executed. This container might exist for some time after the invocation, and if the container is already running the next time the function is called the response will be fast, but after some time the container will be deleted again and a new container has to be created when the function is called again. 

## AWS serverless
### AWS Lambda
You can easily create lambda functions by logging in to the AWS console and going to the lambda section. From there you can click the create function and create your first function!
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f00khjqmqglqsodk8uqh.png)
For now, we will start by creating a function from scratch with NodeJS you can choose any name you like and for now you can select the option: “Create a new role with basic Lambda permissions” but for additional function, it’s advisable to create one general role, if the permissions stay the same,  and select that one for all your functions. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/kfjyhit921n2s5lzk6ge.png)

The actual function can be created on this screen and the two important parts are the trigger and the function code itself. The trigger specifies how the function can be called for instance through the API gateway (more about that later) or a CRON job (eventBridge). The function code is where you’re actually node.js code goes and it looks like this:
```javascript
exports.handler = async (event, context) => {
    // Your code implementation 

    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
```

The event object contains the information about the event that triggered the function, the context object contains information about the runtime in which the lambda is being executed. The response contains the response we want to send back with the status code and body in JSON format. In non-async functions, there is a third parameter you can call to send a response. When you call that callback, Lambda will wait for the event to finish and then return the response or, if something went wrong,  an error. 

Lastly, If you want to test your function you can create a test event on the top left and execute your function inside the console and see if everything works!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fiplvw33rpp7o626k7c7.png)

### AWS API gateway
The API gateway is an interface for AWS services too make them visible to the outside world (or at least your users if you are building in authentication). We are going to create an API from the lambda screen but you can easily create an API from the API gateway page. 

Going back to our freshly created Lambda function we’re going to add a trigger by clicking the “add trigger” button on the left and selecting “API gateway” in the popped up window.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/v0tpdm02372eb09hp8fs.png)

We’re going to create a “REST API” with no security for now so we can select “open” clicking the add button will automatically create our API and our method inside our API. Going to the API gateway page we can test, check, rename, change settings, etc. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3q7p9w0l34sv4jzvi0wq.png)

For a GET request, you probably need to go inside the Method Request and set up URL query string parameters for a POST request you probably need to set up body Parameters.

A few tips: Every time you make a change to a method you need to deploy your API again otherwise it won’t reflect the new changes, it has a very useful test feature built-in, you might need to set up CORS (can be easily done on the above page).

### AWS DynamoDB
Amazon DynamoDB is a simple scalable NoSQL database commonly used with lambda functions. It can be easily used inside a lambda function to store, retrieve, update, or delete data. It’s very straightforward so I won’t be going into too many details this time but here is a usage example:

```javascript
const AWS = require('aws-sdk')

AWS.config.update({ region: 'ap-northeast-1' })
const dynamo = new AWS.DynamoDB({ apiVersion: '2012-08-10' })

exports.handler = async event => {
    const params = {
        TableName: 'TABLE',
        Key: {
            KEY_NAME: { N: '001' }
        },
        ProjectionExpression: 'ATTRIBUTE_NAME'
    }

    dynamo.getItem(params, function(error, data) {
        if (error) {
            const response = {
                statusCode: 400,
                body: JSON.stringify(error)
            }
        } else {
            const response = {
                statusCode: 200,
                body: JSON.stringify(data.Item)
            }
        }
    })

    return response
}
```

It's a simple function with the addition of the call to a DynamoDB table. on error an error response is returned and if the data is successfully retrieved that data is returned. 

Of Course, you need to create a DynamoDB table which can be easily done by going to the DynamoDB service in your console and clicking in the create table button. You only have to specify a table name and primary key to create a table. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f6s1o1m3o8d045ge9p3p.png)

## Finishing notes
In general, you can also manage all the infrastructure/functions (ex. serverless or AWS SAM) with the help of CLI tools and infrastructure as code which is advisable multiple reasons including but not limited to maintenance, simplicity, and with being able to run functions locally.

Not covered but other AWS serverless services include: AWS Amplify ( development framework to build web/mobile applications on AWS), Cognito (authentication), S3 (file storage), CloudFront (CDN), Route53 (DSN service) and Certificate Manager making it easy to build your entire project with AWS ServerLess functions.