Query Postgres from Netlify Functions with Neon serverless driver
Tags: netlify, javascript, postman, postgres
Published: 2024-02-28 08:50:43

[Neon](https://neon.tech/?utm_source=guides&utm_medium=content&utm_campaign=hackmamba) is a serverless Postgres that makes database development and management easy and efficient. Offering modern features like [autoscaling](https://neon.tech/docs/introduction/autoscaling?ref=hm), [auto-suspending](https://neon.tech/docs/introduction/auto-suspend?ref=hm), and [branching](https://neon.tech/docs/introduction/branching?ref=hm), Neon separates compute and storage and scales automatically up or down based on demand, so developers can focus on building their applications without the hassle of managing servers or databases.

Imagine a game company running a massively multiplayer online (MMO) game service that experiences fluctuating user numbers throughout the day. By continuously monitoring the number of online players, the serverless driver can automatically scale the database up or down to meet the changing demand. In peak hours, this ensures that the database can accommodate the growing number of concurrent queries and maintain optimal performance, providing a smooth and lag-free gaming experience for all players.

Conversely, during off-peak hours, when the player counts drop, the serverless driver efficiently recognizes the reduced demand and initiates scaling down the database. This involves releasing unused database resources, such as CPU and memory, to optimize resource utilization and reduce costs. This ensures that companies only pay for used resources, contributing to cost savings and overall efficiency.

In a broader context, the Neon serverless driver is crafted explicitly for data querying in serverless and edge environments, using HTTP or WebSockets rather than conventional TCP. This design choice streamlines operations by removing the requirement for extra infrastructure configuration or worries about TCP connections, saving you time and money. Furthermore, you’ll have the flexibility to leverage Neon's PostgreSQL database service in diverse environments, encompassing Cloudflare Workers, Vercel Edge Functions, and Netlify Functions.

This article will explore how to query Postgres from Netlify Functions using the Neon serverless driver.

## GitHub

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

## Prerequisites

To best follow along with this demo, you’ll need a few things:

- Installation of Node.js
- Basic knowledge of SQL
- Basic understanding of JavaScript
- A neon account. Sign up [here](https://neon.tech/?ref=hm)
- Creating a free Netlify [account](https://www.netlify.com/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity)

## Benefits of using Neon serverless driver
- Low latency: The Neon serverless driver is optimized for low latency, making it ideal for use in serverless and edge environments.
- Easy to use: It is also a drop-in replacement for the popular node-postgres driver, so starting is straightforward.
- Scalable: The Neon serverless driver is scalable and can handle the most diverse workload demands.

## What are Netlify Functions?

[Netlify Functions](https://docs.netlify.com/functions/overview/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity) are serverless functions executed in response to specific events, such as HTTP requests, when users visit a particular URL. Netlify Functions acts as a bridge between the frontend and backend, allowing developers to write backend code that can be integrated with the frontend code and deployed as part of the same project.

With the introduction of the Neon serverless driver, developers can also query the Neon serverless Postgres database directly within Netlify Functions to further enhance the versatility and efficiency of serverless architecture.

## Connecting to Neon Postgres

If you’re a first-time Neon user, go ahead and create a Neon project by [signing up](https://auth.neon.tech/realms/prod-realm/login-actions/registration?client_id=neon-console&tab_id=qGSJZ-GMxgo); then, we can create a project. Neon provides a simplified way of connecting to a created Postgres database using **psql** and a connection string. To obtain a **connection string**, we will navigate to the Neon dashboard, and within the connection details, we will select the database we want to connect to and the type of connection. Neon then creates the connection string as seen below:

![Neon dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8rabbgq1wshp2w4m5ksk.png)

We will take note of the connection string as we will use it to connect and query data from the Neon DB later in the article.


## Creating tables on Neon

Now that we have our dashboard created, we can create a table. First, navigate to the dashboard of interest and access the SQL editor. 

In our case, we will create a table named “POSTS” and add the data below:

```js
CREATE TABLE posts (
  id SERIAL PRIMARY KEY,
  title TEXT NOT NULL,
  content TEXT NOT NULL
);

INSERT INTO posts (title, content) 
  VALUES ('Query Postgres from Netlify Functions with Neon serverless driver', 'This post goes over querying ...');

INSERT INTO posts (title, content) 
  VALUES ('5 reasons why you should start using Neon', 'This post talks about the features Neon provides.');
```
In the SQL code above,  we created a table named “posts” with columns for an auto-incrementing primary key (id), a title (title), and content (content).  Then, we inserted two rows of data into the table, each representing a post with a title and content. 

At this point, our SQL editor should look like the image below:

![Neon’s SQL editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1c48lln9kqamqdv9uwd.png)

To add this table to the dashboard, click “**Run**”. 

Now, if we navigate to "**Tables**,” you’ll see the table “posts” with the two rows of data we inserted.

![The “posts” table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/076lgr0s0f7s1mpocrdt.png)

We’re ready to query this data now that we have our table.

## Creating our application

For this tutorial, we’ll create a new application to query Postgres and use Netlify functions and Neon serverless driver. Start by running the commands below:

```js
mkdir <folder-name> //creates a new folder
cd <folder-name> //navigate into the created folder
```
Next, we’ll initialize a new `Node.js` project by running the command below:

```js
npm init -y
```
This allows us to install and manage dependencies for our project easily.

We will also set up the **`dotenv`** package to manage environment variables locally and after Netlify deployment. To do this, we will install **`dotenv`** using the command below:

```js
npm i dotenv
```
## Installing the Neon serverless driver package

To use the Neon serverless driver within our application, install it using the command below: 

```js
npm install @neondatabase/serverless
```

## Creating a Netlify Function

Netlify Functions are essentially serverless functions that can be deployed and executed on Netlify's serverless platform. To create a Netlify Function, start by creating a directory for these functions at the root of your project. Conventionally, this directory is named **functions**.

We will now create a `.mjs` file for our function inside the **functions** directory. This file should export a handler function, and within this file, we will connect the Neon serverless driver and query Postgres.

We will start by importing the Neon serverless driver.

```js
import { neon } from '@neondatabase/serverless';
```

Then, we’ll import `dotenv` to use in our functions by adding the code below:

```js
require("dotenv").config();
```

Next, we will create a new Neon client:

```js
const sql = neon(process.env.DATABASE_URL!);
```

Now, we can write our first SQL queries:

```js
const result = await sql("SELECT * FROM posts WHERE id = $1", [postId]);   
```

We will get a result that we can then return from the Netlify function:

```js
return {
  statusCode: 200,
  body: JSON.stringify(post),
};
```

Bringing it all together, the Netlify function will look like this:

```js
import { neon } from "@neondatabase/serverless";
require("dotenv").config();

const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
  throw new Error("DATABASE_URL is not defined");
}
const sql = neon(databaseUrl);

exports.handler = async function (event, context) {
  try {
    const postId = parseInt(event.queryStringParameters.postId, 10);
    const result = await sql("SELECT * FROM posts WHERE id = $1", [postId]);
    if (!result || result.length === 0) {
      return {
        statusCode: 404,
        body: JSON.stringify({ error: "Post not found" }),
      };
    }
    const post = result[0];
    return {
      statusCode: 200,
      body: JSON.stringify(post),
    };
  } catch (error) {
    console.error("Error:", error);
    return {
      statusCode: 500,
      body: JSON.stringify({ error: "Internal Server Error" }),
    };
  }
};
```

Here’s what’s going on in the previous code block:

- We imported the `neon` function, which we used to establish a connection to the Neon database using the DATABASE_URL.
- We also imported the **`config`** function from the **`dotenv`** library to handle environment variables.
- We are reading the value of the DATABASE_URL from the environment variable set in the Netlify project dashboard, and we set it to throw an error if the variable is not defined.
- We used the **`neon`** function to establish a connection to the database using the retrieved URL.
- We also executed an SQL query to retrieve posts from the database based on the **`postId`**
- If the `post` variable is null, the code will return a `404` error message. Otherwise, the code will return a `200` OK response and the post data.
- The code returns a `500` status code in the case of an internal server error.

## Configuring `netlify.toml`:

We will create a **`netlify.toml`** file at the root of our project and specify the functions directory, like so:

```js
[build]
  functions = "functions"
```
This tells Netlify where to find our functions.

## Testing the Netlify Function

**Testing locally**
After creating the Netlify function, we can test our integration locally by ensuring we have Netlify’s latest CLI version. Do this by running the command below:

```js
npm install netlify-cli -g 
```

**Configuring the `.env` file**
We will also create a `.env` file in our project’s root folder and add our connection string:

```js
DATABASE_URL=postgresql://[user]:[password]@[neon_hostname]/[dbname]
```
Doing this allows our function to access the `process.env.DATABASE_URL`, which is necessary to connect our function to Neon DB.

We can then start Netlify’s development environment using the command below:

```js
netlify dev
```
At this point, we will see a message like the one below in our terminal:

```js
Server now ready on http://localhost:8888  
```
We can test the success of our implementation by opening up Postman or downloading the latest version [here](https://www.postman.com/downloads/?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity). Afterwards, follow the steps below:
1. Create a `GET` request.
2. Then,  set the URL to the “localhost’s URL/.netlify/<function folder’s name>/<function file name>”. In our case, we will set the URL to this:  `http://localhost:8888/.netlify/functions/function`.
3. Add a query parameter named `postId` with the value `1`.
4. Click “Send”.

Now, we should have our Postman looking like the image below, with the result showing the query of the data with the `postId` of `1` in our Neon DB.


![Querying data locally](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8p2ol4nd6jmgbe6jbfuq.png)

**Testing after deployment**
Usually, we will not always use our applications locally, and there will be cause to deploy our applications beyond our local machines. To do this, we can use Netlify.

As a new user, we can sign up with Netlify [here](https://app.netlify.com/signup?utm_source=hackmamba&utm_medium=blog&utm_id=HMBcommunity). Then, we can select the project we would like to work with; under the project’s “**site configuration**,” we can select the “**environment variables**” option. 

![Netlify’s environment variable view](https://paper-attachments.dropboxusercontent.com/s_263EC0221E12B20D4B8300AFFC529AA5324332A1A7697B4A2876493C273E9E9C_1701782255794_6iIliNTWJB.png)


Using the connection string from the Neon dashboard, we can set the project’s environment variable to the **DATABASE_URL**, like so:


![Netlify’s environment variable view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05m52m1vzlfx5ar7f20p.png)

```js
DATABASE_URL=postgresql://[user]:[password]@[neon_hostname]/[dbname]
```

By storing the DATABASE_URL as an environment variable in Netlify, we can protect the connection string from unauthorized access. It also allows the Netlify function in our code to access the Neon connection string to query the Neon database.

After creating the environment variable on Netlify, we can deploy our application. To complete the final stage of our testing, navigate to the “site configuration” tab and copy the site’s name.


![Netlify’s site configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijg5krz9ffrzoq10b0wv.png)

Let’s navigate back to our Postman and query the data using the site's names. Then, follow these steps:

1. Create a new `GET` request.
2. Then, we will set the URL to the “<Netlify app’s URL>/.netlify/<function folder’s name>/<function file name>”. In our case, we will set the URL to this:  `https://neon-serverless-driver.netlify.app/.netlify/functions/function`.
3. Add a query parameter named `postId` with the value `2` to get the second item in the Neon DB.
4. Click “Send”.

At this point, we should see the second row of data from the `posts` table showing in our Postman:

![Querying data after deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q652d3r5zh1h0e43zznx.png)

We have successfully queried Postgres from Netlify Functions using the Neon serverless driver.

## Conclusion

This article explained how to query Postgres from Netlify Functions using the Neon serverless driver. This approach allows developers to streamline their workflow and query Postgres efficiently, saving time and money.

## Resources

Here are a few additional resources to help you through this process:

- [Neon serverless driver documentation](https://neon.tech/docs/serverless/serverless-driver?ref=hm)
- [Connecting Neon with psql](https://neon.tech/docs/connect/query-with-psql-editor?ref=hm)
- [Netlify functions](https://docs.netlify.com/functions/overview/)