Serverless offline (run it locally)

Some developers prefer to do their work locally and make sure everything works on their own machine before deploying to an environment. This is quite hard to do with cloud-native applications because, usually, the services we use are managed services that can't be run ourselves on a server outside of the cloud provider. For example, you can't run the full-blown Amazon S3 service yourself in your own data center or virtual machine. 

Some of the benefits that developers are looking for when developing locally are as follows:

  • The speed at which new code or changes can be validated and tested. Not every code change requires a deployment to be pushed to a cloud service.
  • A better handle on the costs that are incurred if the cloud service pricing model is not easily understood.
  • Enabling local debugging can close iteration loops.

Over the years, though, there have been advancements in local development and new options have been created. Now, with AWS, we can run DynamoDB locally, run API Gateway locally using the Serverless Application Model, invoke lambda functions locally, and launch some local endpoints to be able to test applications before deploying them to ECS.

This chapter is about the Serverless Framework specifically, so let's have a look at our options when it comes to running services on our own machines and developing with the framework. 

First up, we have the out-of-the-box command to invoke our function locally. After all, functions are only code, so there's not a whole lot to emulate there. The following command shows us the syntax for invoking a function locally using the code we have already developed on our desktops:

sls invoke local -f <function-name>

The context object is injected with some mock data, the function is invoked, and we should get the output we are expecting. It's a good idea to run this command while you're developing functions before pushing them to AWS, where the code is more integrated into the environment. Any obvious syntax errors that aren't picked up by your IDE's linter are likely to be surfaced here.

When developing locally, there are a couple of plugins that you can install that will make your life easier, as follows:

  • Serverless offline plugin
  • Serverless DynamoDB Local plugin

If you need a more integrated environment for the Lambda function code to run in, you may turn to the serverless offline plugin (https://github.com/dherault/serverless-offline). This is a plugin that adds emulation for API Gateway, as well as the Lambda execution environment. It currently supports Node.js, Python, Ruby, and Go and has a good scope of features that you might need.

Another useful plugin you might need is DynamoDB Local (https://serverless.com/plugins/serverless-dynamodb-local/). This will allow you to reference the endpoint of an instance of the DynamoDB service that is running on your own machine.

Let's have a go at installing and configuring the offline plugin and the DynamoDB Local plugin. Remember that these are plugins that developers in the community have written, and they all contribute to the functionality that the framework can provide because of its modular design—awesome.

Let's start by installing these two useful plugins in our project directory. We'll use the --save-dev switch in the command so that the packages are included in the development dependencies and not the application dependencies—in other words, these packages aren't needed for the actual function to run in production. Let's get started:

  1. Install the plugins from the public node package registry:
npm install serverless-offline serverless-dynamodb-local --save-dev
  1. The next thing we need to do is update our serverless.yml file so that we can add a plugins declaration so that the plugins are imported. The best place to add the following block is near the bottom of the serverless.yml file.
plugins:
- serverless-offline
- serverless-dynamodb-local
  1. Next, we actually need to install the DynamoDB Local service, and we can use the framework to do this for us. The following command will install the necessary files into our project directory, under a hidden directory called .dynamodb:
sls dynamodb install

We should probably add some DynamoDB resources to our serverless.yml file while we're at it.

  1. Add the following block under the function declaration. Where we can, we'll try to follow the DynamoDB example from Chapter 5Leveraging AWS Services, so that we can use this knowledge again. The resources block we are adding will give DynamoDB Local some configuration to start with. When we deploy the same thing to AWS, the Serverless Framework will translate our configuration into CloudFormation to deploy the DynamoDB tables:
resources:
Resources:
photosMetadataTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: photos-metadata
AttributeDefinitions:
...
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
  1. We need to add some attribute definitions as well. You can create your own or use my suggested following data points. Substitute the ellipsis in the preceding resource block with some attribute definitions. The reference documentation for attribute definitions can be found at https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-attributedef.html
          - AttributeName: id
AttributeType: N
- AttributeName: FILENAME
AttributeType: S
- AttributeName: FOCAL_LENGTH
AttributeType: N
- AttributeName: CAMERA_MAKE
AttributeType: S
- AttributeName: FLASH_FIRED
AttributeType: BOOL

  1. We also need to add a customization to the YML file to engage DynamoDB Local. Add the following to the end of our existing file:
custom:
dynamodb:
stages:
- dev
  1. Now, we want to run up the serverless offline system. This starts the local DynamoDB service, which is configured to listen on port 8000. Then, it will start up the endpoint emulator for API Gateway, which will listen on 3000. Use the following command to start the server:
sls offline start

The node server running serverless offline will stay in the foreground and output any log messages to stdout. Now that we know we have a live local endpoint, we can hit it with some requests!

  1. Use the curl command to make a request to your API endpoint running on the local server:
curl -X GET http://localhost:3000/hello

We can also browse to a useful console for the local DynamoDB instance at http://localhost:8000/shell. This is a web console that makes it easier for us to prepare code to use in our functions. You can execute code snippets directly against your table, with JavaScript only being supported at the moment.

The last thing we should cover is how we can let the function know that it is running locally so that we can update the endpoint for DynamoDB to use our local one. Thankfully, the serverless offline plugin creates a Boolean environment variable called IS_OFFLINE. The plugin sets the variable to true when the function is running locally.

We should be able to use the following function when we set up our client:

const dbClient = new AWS.DynamoDB.DocumentClient(
process.env.IS_OFFLINE ? {region: 'localhost', endpoint: 'http://localhost:8000'} : {}
);

It's as easy as that. When we're finished using the serverless offline server, we can hit Ctrl + C to kill the node server and stop and clean up the DynamoDB instance that's running. 

Next, we are going to learn about testing and how to troubleshoot when things go wrong with a lambda function. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.52.7