Query Postgres from CloudFront functions with Neon serverless driver
Tags: postgres, neon, aws, serverless
Published: 2024-03-01 21:31:33

[PostgreSQL](https://www.postgresql.org/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity) is an open-source object–relational database system that is robust, reliable, and highly performant. It uses and extends SQL with features that can handle complicated workload data.

In this article, we will use [AWS CloudFront functions](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity) to query a Postgres database using [](https://neon.tech/docs/serverless/serverless-driver?utm_source=guides&utm_medium=content&utm_campaign=hackmamba)[Neon serverless driver](https://neon.tech/docs/serverless/serverless-driver?ref=hm). Let’s get started!

## GitHub

Check out the source code [here](https://github.com/obinnadtq/neon-serverless-driver?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity).

## Prerequisites

To follow along with this tutorial, you’ll need the following:

- An [AWS](https://aws.amazon.com/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity) account.
- A [Neon](https://neon.tech/?ref=hm) account.
- Basic knowledge of JavaScript.
- Basic knowledge of SQL.

## New to Neon?

[Neon](https://neon.tech/?ref=hm) is serverless Postgres. If you’re a developer, Neon handles all your Postgres database needs, allowing you to focus on building their applications. Neon separates storage and computing, and this offers certain benefits. Some of these include:


- **Pay** **for** **only what** **you** **use**: When there is a lot of data to be stored, you’ll only pay for storage and not for computing, which helps save costs.


- **Flexible scaling**: Storage and compute can be scaled independently. When more storage and fewer compute resources are needed, we can scale up storage resources and scale down compute resources independently. 


- **Better utilization of resources:** The separation of compute and storage helps to utilize resources better. When more storage and fewer compute resources are required, you can opt for a less expensive subscription option and use the resources for something else.


## What is Neon serverless driver?

Before going into what Neon serverless driver is, let’s briefly cover two terms: **Serverless** and **Edge** **computing**.

**Serverless computing** is a model that provides backend services to users so the users can focus on building their user-facing applications. It abstracts all the server infrastructure for the user. 

**Edge computing** is a model that provides low latency and high-performant applications by placing cloud resources at the network's edge close to where they are needed.

[Neon serverless driver](https://github.com/neondatabase/serverless?ref=hm) is a Postgres driver that enables the query of data from serverless and edge environments over HTTP or WebSockets. It is designed for JavaScript and TypeScript-enabled serverless and edge environments. 

This tutorial will use Amazon CloudFront with Neon’s serverless driver. The following section introduces Amazon CloudFront.

## What is Amazon CloudFront?

[Amazon CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity) is a web service that delivers web content to users through a broadly distributed network of data centers known as **edge locations**. When users request content via CloudFront, they are redirected to the edge location with the lowest latency (in terms of time) and provide the content with the best performance. 

For example, when a user requests data not served via CloudFront, there is a lot of network routing before the data gets to the user. There is a high latency and possibly some data loss. However, with CloudFront, data delivery is more efficient. The request is routed to an edge location that will provide the data quickly and with high performance and reliability.

CloudFront functions are lightweight functions in JavaScript for high-scale, latency-sensitive Content Delivery Network (CDN) customizations. They modify the requests and responses made to a CloudFront distribution. CloudFront functions can be built, tested, and deployed entirely within CloudFront.

## Getting started with Neon

If there is an existing Neon account and project, skip this section and proceed to the next section.

We must create a Neon project and database to use Neon's serverless driver. To sign up on Neon, navigate to [Neon’s website](https://neon.tech/?ref=hm) and click the **Signup** button. After clicking the **Signup** button, it directs us to the signup page with options for signing up either with Email, GitHub, or Google accounts.

![Signing up with Neon](https://paper-attachments.dropboxusercontent.com/s_7D022530D27B0FC560A1ABF2D45611F1659A038270D3E298E29189ADC6D7D57D_1699990369499_image.png)


After signing up, we are redirected to the **Getting started** page, where we will enter the project and database names. For this tutorial, our project name is **Neon-Cloudfront,** and the database name is **neonCloudfront.**

After creating the project, we are redirected to the project console.

![Neon project](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701036305072_image.png)

## Creating a table in our database

In this section, we will create a table in our **neonCloudfront** database. We will create a `students` table and insert data into it. To do these, we will run the commands below in the SQL Editor in our Neon project and click the **Run** button.

```SQL
CREATE TABLE students (
  id SERIAL PRIMARY KEY,
  firstname TEXT NOT NULL,
   lastname TEXT NOT NULL
  );
    
INSERT INTO students (firstname, lastname)
  VALUES
   ('Obinna', 'Hilary'),
   ('Bob', 'Marley'),
   ('Charles', 'Darwin'),
   ('David', 'Beckham'); 
```

![Creating Students table](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701117181252_image.png)


After clicking the **Run** button and the operation is successful, we can confirm by clicking the 
**Tables** menu on the left. There, we will find the `students` table with the data.


![Verifying the creation of Students table](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701117544826_image.png)

## Creating an AWS Lambda function using Neon serverless driver 

[AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity) is a serverless computing service that allows us to run code without managing or provisioning servers. AWS Lambda runs our code on highly-available compute infrastructure and handles all the compute resources, including server and operating system maintenance, scaling, and logging. The code is organized in AWS Lambda via Lambda functions. The functions run when needed.

Using the Neon serverless driver, we will create a Lambda function that queries our database. We will use the serverless framework to create our Lambda function. Navigate to the [s](https://www.serverless.com/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity)[erverless framework’s website](https://www.serverless.com/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity) and click the **Sign up** button.

```powershell
npm install -g serverless
```

- Create a `neon-lambda` project directory and navigate to it using the commands below.

```powershell
mkdir neon-lambda
cd neon-lambda
```

- Next, run the command below in the terminal to create a serverless project.

```powershell
serverless
```

You’ll encounter a series of prompts. Follow the prompts as shown below! Note that you’ll be required to enter our AWS credentials.

![Creating a serverless project](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701119255909_image.png)


  
We can now verify that our Lambda function has been deployed by checking our AWS console.


![AWS Lambda function](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701119375647_image.png)

- Install the necessary dependencies needed for our Lambda function. The first one is the `Neon serverless driver`. To install, we will run the command below.

```powershell
npm install @neondatabase/serverless
```

Then, install `dotenv` to enable us to read environment variables. To do this, run the command below in the terminal.

```powershell    
npm install dotenv
```

- Then, we will create a `.env`  file in our project root to store our environment variables. The file will have only one variable `DATABASE_URL``,` which is the connection to our Neon `neonCloudfront` database. We will click the Dashboard menu in our Neon project to get the URL.
![Connection details](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701120947098_image.png)

- Next, we will create our Lambda function to fetch all `students` data from our database table. To do this, we will update the `index.js` file in our `neon-lambda` project we created in the previous step. The file should look like this at this point.

```javascript
'use strict';

const { neon } = require('@neondatabase/serverless');
require('dotenv').config();

module.exports.getAllStudents = async () => {
  var sql = neon(process.env.DATABASE_URL);
  var rows = await sql('SELECT * from students');
  return {
    statusCode: 200,
    body: JSON.stringify(rows),
  };
};
```    

The code above does the following:
    
- Lines 3 - 4: we imported the necessary functions, i.e., `neon` from the `Neon serverless driver` and `dotnev`.
    
- Line 7:  we called the `neon` function with the `DATABASE_URL` environment variable as a parameter, and it returned a result named `sql`.
    
- Line 8: we used the returned result, a function that takes an SQL query as a parameter. In this case, we query all the data from the `students` table in our database.
    
- Lines 9-13: we returned the result to the caller.

- Next, we will update the `serverless.yaml`  file. The file should look like this:

```yaml
org: obinna
app: neon-lambda
service: neon-lambda
frameworkVersion: '3'
provider:
  name: aws
  runtime: nodejs18.x
  environment:
    DATABASE_URL: '<Database_url>'
functions:
  getAllStudents:
    handler: index.getAllStudents
    events:
      - httpApi:
          path: /students
          method: get
```    
The `server.yaml` file specifies the configuration of our Lambda functions to be deployed. We specified the `getAllStudents` function we implemented in the previous step. We also specified the HTTP API to make the data available via an endpoint.

- Run the command below in the terminal to deploy the Lambda function.

```powershell
serverless deploy
```

We can confirm that the Lambda function deployed successfully by checking the AWS console.


![GetAllStudents Lambda function](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701122562976_image.png)

## Creating a CloudFront distribution

In this section, we will create a CloudFront distribution. To do this, we will go through the following steps.


- In our AWS console, enter CloudFront in the services search bar and click on the CloudFront result.
- On the CloudFront page, click the **Create distribution** button to create a new CloudFront distribution.
![Create Cloudfront distribution 1](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701213158025_image.png)

- After clicking the Create distribution button, you’ll get redirected to the **Create distribution** page. We will select the `dev-neon-lambda` in the Origin domain field. We can use the defaults of the other fields. Then, click on **Create distribution** button at the bottom of the page.
![Create CloudFront distribution 2](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701213723197_image.png)

- After creating the distribution, we will see our CloudFront distribution on the CloudFront homepage. On the last modified column, we will see it `Deploying`. After it has been deployed, the status of the column changes to the date and time it was successfully deployed.


![Create CloudFront distribution 3](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701214109459_image.png)

## Querying the database using a CloudFront Function

In this section, we’ll create a CloudFront function to query the `students` table in the database. To create a CloudFront function, click the **Functions** menu on the CloudFront page.

![Creating a CloudFront function 1](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701294671938_image.png)

Next, we will click the **Create function** button to create a function. Let’s name the function  `queryStudentData` and click the **Create function** button.

![Creating a Cloudfront function 2](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701294964145_image.png)

After creating the function, paste this code into the code editor on the CloudFront function page and click the **Save changes** button.

```javascript
function handler(event) {
  var request = event.request;
  request.uri += '/students';
  return request;
}
```
he code above manipulates the request made to our CloudFront distribution and appends `/students` to the URL to query our students data.

Next, let’s publish our function. Click on the **Publish** tab and click the **Publish function** button.


![Publish function](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701295833665_image.png)


After clicking the **Publish function,** we will associate our function with our CloudFront distribution. In the **Associated distributions** card, we click the **Add association** button, and it opens a dialog where we select and associate our distribution. Since we are modifying the request, choose `Viewer request` and “Default” for cache behavior in the `Event type` field.


![Associating a function to a distribution](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701296061841_image.png)


After associating with our CloudFront distribution, we will wait for our function to update for some time. After it has been successfully updated, we will enter our CloudFront distribution domain name and use it in Postman to make a query. To get the domain name of our CloudFront distribution, click on the **Distributions** menu on the CloudFront home page.


![Getting the domain name of CloudFront distribution](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701214109459_image.png)

![Postman query](https://paper-attachments.dropboxusercontent.com/s_AF34EF72819069460B99B4D51DCCF6BCF75148281A51FC500089AA5BB40AE822_1701296833558_image.png)


The student data is successfully returned from our database. We can confirm that our CloudFront function successfully connected to our Neon Postgres database using the Neon serverless driver.

## Conclusion

This tutorial showed how to use Neon serverless driver with AWS CloudFront function. We provided some details about CloudFront distribution and functions. We also delved into AWS Lambda and created a Lambda function. Finally, we used the Neon serverless driver to connect our function to our Neon database and queried the database successfully. 

Neon serverless driver can be used with other serverless and edge environments over HTTP or Websockets. Some of these edge environments include Vercel Edge functions and Cloudfare workers.

## Resources
- [Neon](https://neon.tech/docs/introduction?ref=hm)
- [Neon serverless driver](https://neon.tech/docs/serverless/serverless-driver?ref=hm)
- [Using Neon with AWS Lambda.](https://neon.tech/docs/guides/aws-lambda?ref=hm)
- [Amazon Cloud](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity)[F](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity)[ront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity)
- [PostgreSQL](https://www.postgresql.org/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity)
[](https://neon.tech/docs/serverless/serverless-driver)