This article will discuss some basics about the Serverless platform, Lambda@Edge, which is a feature of Amazon CloudFront, and how to deploy the Next.js app with a Serverless framework.

We will be focused on the AWS cloud provider, which is called Lambda@Edge or AWS Lambda, but it is also good to mention that there are two more significant providers:

  • Microsoft Azure: Azure Functions

  • Google Cloud: Cloud Functions

Before Serverless

Traditionally, we’ve built and deployed web applications where we have some control over the HTTP requests made to our server. Our application runs on that server, and we are responsible for provisioning and managing the resources for it. There are a few issues with this.

  1. We are charged for keeping the server up even when we are not serving out any requests.

  2. We are responsible for the uptime and maintenance of the server and all its resources.

  3. We are also responsible for applying the appropriate security updates to the server.

  4. As our usage scales, we need to manage to scale up our server as well. And as a result, we tend to scale it down when we don’t have as much usage.

For smaller companies and individual developers, this can be a lot to handle. This ends up distracting us from the more important job we have - building and maintaining the actual application.

So, we will start with a question that brings you here, and that is:

What is Serverless?

Serverless Computing, or just Serverless, is an execution model where the cloud provider (AWS) is responsible for executing a piece of code by dynamically allocating the resources and only charging for the number of resources used to run the code. The code is typically run inside stateless containers triggered by various events, including HTTP requests, database events, queuing services, monitoring alerts, file uploads, scheduled events, etc. 

While Serverless abstracts the underlying infrastructure away from the developer, servers are still involved in executing our functions.

Stateless Functions

Your functions are typically run inside secure (almost) stateless containers. This means that you won’t be able to run code in your application server that executes long after an event has been completed or uses a prior execution context to serve a request. You have to effectively assume that your function is invoked in a new container every single time.

AWS serverless platform

AWS Lambda is a serverless computing service provided by AWS. 

AWS provides a set of fully managed services that you can use to build and run serverless applications. Serverless applications don’t require provisioning, maintaining, and administering servers for backend components such as compute, databases, storage, stream processing, message queueing, and more. You also no longer need to worry about ensuring application fault tolerance and availability. Instead, AWS handles all of these capabilities for you.

Here is an example of a Weather application that uses several Amazon Web Services:

image-20200430-114027

Another good feature is a data processing and an example of Image Thumbnail Creation:

image-20200430-114403

Lambda Function

anatomy-of-a-lambda-function

Here myHandler is the name of our Lambda function. The event object contains all the information about the event that triggered this Lambda. In the case of an HTTP request, it’ll be information about the specific HTTP request. The context object contains info about the runtime our Lambda function is executing in. After we do all the work inside our Lambda function, we call the callback function with the results (or the error), and AWS will respond to the HTTP request with it.

Lambda@Edge

Lambda@Edge is a feature of Amazon CloudFront that lets you run code closer to your application users, which improves performance and reduces latency. With Lambda@Edge, you don't have to provision or manage infrastructure in multiple locations around the world. You pay only for the compute time you consume - there is no charge when your code is not running.

With Lambda@Edge, you can enrich your web applications by making them globally distributed and improving their performance — all with zero server administration. Lambda@Edge runs your code in response to events generated by the Amazon CloudFront content delivery network (CDN). Just upload your code to AWS Lambda, which takes care of everything required to run and scale your code with high availability at an AWS location closest to your end-user.

How does it work?

Here is a simple schema of how Lambda@Edge works:

image-20200430-120518

Since Lambda@Edge uses cases, there are a lot of functionalities that it can provide you with, such as:

  • Website Security and Privacy

  • Dynamic Web Application at the Edge

  • Search Engine Optimization (SEO)

  • Intelligently Route Across Origins and Data Centers

  • Bot Mitigation at the Edge

  • Real-time Image Transformation

  • User Authentication and Authorization

  • User Prioritization

  • User Tracking and Analytics

And of course, many more… Detailed schemes and explanations can be found on the AWS Lambda@Edge page.

Serverless Next.js deployment

First of all, we will start by installing Serverless globally on our computer:

1npm install -g serverless

Then get your credentials by following this guide https://github.com/serverless/serverless/blob/master/docs/providers/aws/guide/credentials.md

Now let’s create our Next.js app:

1npx create-next-app

and install the Next.js component in the created app:

1npm install serverless-next.js --save-dev

The following steps include creating a few files that will help us configure our app:

1touch next.config.js
2touch .env
3touch serverless.yml

File next.config.js allows us to deploy our app to a serverless environment and is pretty simple:

1module.exports = {
2  target: "serverless",
3};

File .env is where we enter our AWS Credentials in the following format:

1AWS_ACCESS_KEY_ID=accesskey
2AWS_SECRET_ACCESS_KEY=secretaccesskey

And in our serverless.yml file, we will write down the whole configuration for deployment:

1nextApp:
2  component: "serverless-next.js"

Yes, this is the entire configuration needed.  

Now, all we need to do is deploy our app:

1npx serverless

We can also remove by using:

1npx serverless remove

Custom domains

When we deploy our serverless app, we get a randomly generated URL.

We can set a custom domain for our application. serverless-next.js takes care of associating the domain with your CloudFront distribution, creates the sub domain in Route53, and even sets up the SSL Certificate using AWS ACM. However, this feature is optional and looks like this:

1# serverless.yml
2myApp:
3 component: serverless-next.js
4 inputs:
5   domain: ["www", "example.com"] # [ sub-domain, domain ]

Conclusion

image-20200504-105256

We have covered the basics of the Serverless platform, which is a potent tool. The combination of using Next.js and Serverless gives us lots of benefits such as:

  • Straightforward configuration

  • Next nine features:

    • Server-side rendered pages

    • API Routes - Also deployed to Lambda@Edge.

    • Automatic pre-rendering - Some of your pages might not be SSR. Next.js compile these types of pages to HTML at build time. serverless-next.js takes advantage of this and deploys them to S3. Lambda@Edge in CloudFront then takes care of forwarding requests to static pages to S3.

    • Client assets - Build files generated by Next.js, such as webpack chunks, css files, etc., are uploaded to S3. In this case, Lambda@Edge does not need invoking as any requests to _next/* are served by CloudFront from S3.

    • User static / Public folders - User assets like images in the static folder or root level resources in your public folder are uploaded to S3. Like build assets, CloudFront serves these assets from S3.

  • Fast deployments