Studio Terabyte is a full stack web development studio who finds and builds solutions that fit your project
When we think of web applications we usally think of servers that are responsible for receiving HTTP requests, processing the request, running some business logic and finally returning a result. You are not only responsible for the business logic, but also the server infrastrucutre itself. There are a few issues with this:
Having to deal with all this DevOps work can end up distracting you from the more important job of building and maintaining the actual app your users are paying for. Even when you are a large business and have a DevOps team, not being able to quickly deploy and test your code as a developer can slow things down. This is where serverless comes in
Serverless computing (or serverless for short), is a setup where the cloud provider (AWS, Azure, or Google Cloud) is responsible for executing a piece of code by allocating the server resources (so they manage all the server stuff mentioned above) based on real-time usage. You are only charged for the time your code is running. The code is typically run inside stateless containers that can be triggered by a variety of events including http requests, database events, queuing services, monitoring alerts, file uploads, scheduled events (cron jobs), etc. There are a number of serverless offerings such as:
While serverless abstracts the underlying infrastructure away from the developer, servers are still involved in executing our functions.
Since your code is going to be executed as individual functions, there are a couple of things that we need to be aware of.
The biggest change that we are faced with while transitioning to a serverless world is that your application needs to be architectured in the form of functions. You might be used to deploying your application as a app. But in the serverless world you are typically required to adopt a more microservice based architecture.
Your functions are typically run inside secure (almost) stateless containers. This means that once the code has finished running, the container will be shut down and a new will be spun up for the next event. You can not rely on the output of the function to still be there when the next event comes in, so make sure that each event can be handled individually. This also relates to the next topic.
Since your functions are run inside a container that is brought up on demand to respond to an event, there is some latency associated with it. This is referred to as a Cold Start. Your container might be kept around for a little while after your function has completed execution. If another event is triggered during this time it responds far more quickly and this is typically known as a Warm Start.
The duration of cold starts depends on the implementation of the specific cloud provider and how your code has been written.
Aside from optimizing your functions, you can use simple tricks like a separate scheduled function to call your function every few minutes to keep it warm. Serverless Stack Framework (SST) has pre-built tools for this.
Now, one of the most popular options for serverless apps is AWS. AWS offers a number of different services and tools which can be used together such as DynamoDB, Lambda Functions, S3 and Cognito.
Since these services run on AWS, it can be tricky to test and debug them locally. And a big part of building serverless applications, is being able to define your infrastructure as code. This means that we want our infrastructure to be created programmatically. We don’t want to have to click through the AWS Console to create our infrastructure each time.
To solve these issues we can use Serverless Stack Framework (SST).
SST makes it easy to build serverless applications by allowing developers to:
It does this by using AWS CDK.
AWS CDK (Cloud Development Kit) allows you to use TypeScript, JavaScript, Java, .NET, and Python to create AWS infrastructure.
So for example, a CloudFormation template that creates our DynamoDB table would now look like.
Without code:
COPY- Resources:
- NotesTable:
- Type: AWS::DynamoDB::Table
- Properties:
- TableName: ${self:custom.tableName}
- AttributeDefinitions:
- - AttributeName: userId
- AttributeType: S
- - AttributeName: noteId
- AttributeType: S
- KeySchema:
- - AttributeName: userId
- KeyType: HASH
- - AttributeName: noteId
- KeyType: RANGE
- BillingMode: PAY_PER_REQUEST
Defined as code:
+ const table = new dynamodb.Table(this, "notes", {
+ partitionKey: { name: 'userId', type: dynamodb.AttributeType.STRING },
+ sortKey: { name: 'noteId', type: dynamodb.AttributeType.STRING },
+ billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
+ });
The first thing to notice is that the resources are defined as class instances in JavaScript. That’s great because we are used to thinking in terms of objects in programming languages. And now we can do the same for our infrastructure. Second, we can reuse these objects. We can combine and compose them. So if you always find yourself creating the same set of resources, you can make that into a new class and reuse it!
CDK is truly, infrastructure as code.
SST provides a cloud native local development environment that gives you instantaneous feedback on edits made in your Lambda function code. Changes are automatically detected, built, and live reloaded in under 10 milliseconds. And you can use breakpoints to debug your functions in your favorite IDE.
Live Lambda Development is an SST feature that allows you to debug and test your Lambda functions locally, while being invoked remotely by resources in AWS. It works by proxying requests from your AWS account to your local machine.
The SST Console is a web based dashboard to manage your SST apps.
The SST Console does a couple of things:
It also lets you explore resources you are using within your app. You can read more in documentation.
So, now that you have an idea what SST can do the question is: Should you use it? I believe that it is an invaluable tool when you want to go serverless. However, make sure that the app you are building actually benefits from this architecture. Don't overengineer your app just because it looks like everyone is doing it!