Getting Started With Neon Branching — Smashing Magazine

By admin
Getting Started With Neon Branching


8 min
TIME

read

Share on Twitter, LinkedIn

Branches are a really nice (and safe) way to configure or reconfigure your database without fear of screwing up the production database. Let’s take a closer look at how branching works with Branches are a really nice (and safe) way to configure or reconfigure your database without fear of screwing up the production database. Let’s take a closer look at how branching works with

Neon
ORG

, and the good news is, you probably already know how it works!

Branching off to make code changes is a tried and tested approach to software development, but why should database development be any different? Well, branching with

Neon
ORG

allows you to make changes to your database without affecting the production environment. If you’re familiar with Git, you’ll feel right at home.

For demonstration purposes, and to explain how branching works, I’ll use a typical “contact us” form and make a “fictional” change.

The form currently submits the following fields.

name

email_address

company_website

company_size

message

The form works by sending the form data using a client-side request to a Vercel Edge Function, which in turn securely connects to a

Neon Serverless Postgres
ORG

database.

Here’s a snippet of the client-side fetch request.

const handleSubmit = async (event) => { event.preventDefault(); const data = Object.fromEntries( new FormData(event.currentTarget).entries() ); try { await

fetch(‘/api
ORG

/submit’, { method: ‘POST’, body: JSON.stringify({ data }), }); } catch (error) { console.error(error); } };

And here’s a code snippet of

the Edge Function
ORG

that destructures the form values from the request body and INSERT s them into a table named contact_us .

import { neon } from ‘@neondatabase/serverless’; export default async function

handler(req
ORG

) { const { data: { name, email_address, company_website, company_size, message }, } = await new Response(req.body).json(); const

sql = neon(process.env
ORG

.DATABASE_URL); try { await sql`INSERT

INTO contact_us
ORG

(name, email_address, company_website, company_size, message) VALUES( ${name}, ${email_address}, ${company_website}, ${company_size}, ${message} );`; return

Response.json
PERSON

({ message: ‘A Ok!’, }); } catch (error) { return

Response.json
PERSON

({ message: ‘Error’, }); } } export const config = { runtime: ‘edge’, };

The change I’d like to make will happen “behind the scenes”, and along with information entered by the user, I also want to capture and store the geographical location of where in the world the form was submitted.

To do this I’m going to use

Vercel
PERSON

’s geolocation helper function from the

@vercel
PRODUCT

/edge package. The changes I’ll be making will affect both

the Edge Function
ORG

and the database table schema.

I don’t want to change the table schema on the live production database until I’ve tested it all works correctly, and thanks to branching, I don’t have to.

Here’s how I’d go about making a change of this nature.

Creating a branch with

Neon

Neon
PRODUCT

has a super cool browser console (just look at it! 😍), and all database changes can be made, and tested in the browser, no messing around with a dweeby-looking terminal window!

The project is called branching-sample . The primary branch name is main . To create a branch, click this button.

Clicking “Create branch” will take you to the next screen where I’ll configure the new branch.

This will be the name of the new branch. Typically I’ll name the branch the same as the Git branch. (I’ll show you that shortly). This is the parent branch that I want to “branch off” from. Normally it’s always going to be main, but in some cases, I might branch off from another branch. These are the branch configuration options. For this demonstration, I’ll be branching using the Head option. There are a number of reasons why branching from a specific point in

Time
ORG

, or LSN are more suitable. E.g, In cases where you might be performing a backup, or debugging an issue and want to see “when things went wrong”. Head: Creates a branch with data up to the current point in time. Time: Creates a branch with data up to the specified date and time. LSN: Creates a branch with data up to the specified

Log Sequence Number
PRODUCT

(LSN) In order to test the changes I’ll be making in

the Edge Function
FAC

(which I’ll explain in a moment), I’ll want to ensure I’m inserting data correctly. By creating a compute endpoint with the branch, I can do this without worrying that I’ll be messing up the production database! A button that will create the new branch

Clicking “Create the branch” will take you to the next screen.

This is where things get really, really cool!

This is a new connection string for an entirely new database, and it was set up almost instantly and contains “real” data! A key point to communicate is that any data pushed to this branch won’t appear in the production environment, but this “copy” of the database will be identical to the production database, in line with where you branched off from, in my case, Head. The copy button allows you to quickly copy the connection string.

Add the branch connection string to your local development environment.

Using the handy little “copy” button, I can copy the new connection string and add it to my .env file.

This is just my preferred approach of course but, in my .env file, I comment out the production database connection string, and add a new variable using the same name of DATABASE_URL . I then add a comment above it with the name of the branch I used in the

Neon
ORG

console. And for what it’s worth, my Git branch is also named the same way.

I’ve found this to be super helpful when I have multiple branches on the go at the same time. That

one
CARDINAL

little comment above the connection string helps me identify which branch it relates to in the

Neon
ORG

console.


Switch
ORG

branches in the

Neon
ORG

console

Before going too much further I like to double check I’m viewing the correct branch in the

Neon
ORG

console. If you’ve followed the steps above you should be able to see your new branch when selecting “Branches” from the navigation.

Yep, this is the new branch I created.

Clicking the branch name will take you to the next screen.

From the SQL Editor, you can also switch between branches which makes it easy to run queries against different branches.

Alter the database table schema

Before making any changes to the code I prepare the database and test it all works by running

SQL
ORG

commands directly in

Neon
ORG

’s SQL Editor.

Show the current table schema

To work out what the current schema for the contact_us table looks like, I can navigate to “Tables” in the navigation and see the schema for the table.

Showing the branch you’re currently on. The schema for the contact_us table.

I know the change I want to make will require that I add

two
CARDINAL

new columns which will store geolocation data. The

two
CARDINAL

new column names will be as follows.

country_code city


ALTER
ORG

the table

To add the new columns I use the following

SQL
ORG

command.


ALTER TABLE contact_us ADD COLUMN country_code VARCHAR
ORG

, ADD COLUMN city

VARCHAR
ORG

;

Using the

ALTER
ORG

TABLE command I’m adding both the above-named columns and giving them a data type of

VARCHAR
ORG

.

To double-check check the changes were made correctly I can head back over to “Tables” and take a look at the table schema again.

Showing the branch you’re currently on. The city and country_code columns have been added to the schema for the contact_us table.

Now that I know the table is configured correctly, I’ll head back to the “SQL Editor” and run a quick INSERT to check there are no errors.

INSERT statement to add a row which includes values for the new country_code and city column. Confirmation the request was successful.

If I SELECT * FROM contact_us , I’ll see the row I added will contain the country_code and city columns.

A new row has been added with the correct values for country_code and city .

This test data will only be added to the branch, not the production environment, so you can safely run as many tests as you like without polluting the “real” data.

With the change confirmed to be working, I can now switch back to the main branch, and run the

ALTER
ORG

command from earlier.

This will apply the changes to the production database!


ALTER TABLE contact_us ADD COLUMN country_code VARCHAR
ORG

, ADD COLUMN city

VARCHAR
ORG

;

I can double, double check this worked by going to “Tables” again in the console. If all is ok, I can safely delete the development branch: feat/geolocation-data and move on to making the required changes to my Edge Function 🎉

Install @vercel/edge

The values I’ll be adding to the INSERT statement can be extracted from incoming requests to

an Edge Function
ORG

. To access these values I’ll use the geolocation helper function from the

@vercel
PRODUCT

/edge package .

To use this package, I’ll

first
ORDINAL

need to install it.

npm install

@vercel
PRODUCT

/edge

I can then use it in my Edge Function. Here’s a diff of the change. You can see the full diff for the PR on my GitHub here.

import { neon } from ‘@neondatabase/serverless’; + import { geolocation } from

‘@vercel
WORK_OF_ART

/edge’; export default async function

handler(req
ORG

) { const { data: { name, email_address, company_website, company_size, message }, } = await new Response(req.body).json(); + const { country, city } = geolocation(req); const

sql = neon(process.env
ORG

.DATABASE_URL); try { await sql`INSERT

INTO contact_us
ORG

( name, email_address, company_website, company_size, message, + country_code, + city ) VALUES( ${name}, ${email_address}, ${company_website}, ${company_size}, ${message}, + ${country}, + ${city} ); `; return

Response.json
PERSON

({ message: ‘A Ok!’, }); } catch (error) { return

Response.json
PERSON

({ message: ‘Error’, }); } } export const config = { runtime: ‘edge’, };


One
CARDINAL

snag with this package when testing locally is, both the country and city will be null . The geolocation function will only return actual values when

the Edge Function
ORG

has been deployed. ☝️

And that’s it, brrrrranches!

Branches are a really nice (and safe) way to configure or reconfigure your database without fear of screwing up the production database, and in my experience, branches can really help speed up development time, and it doesn’t matter how many test INSERT s I run, test data will always remain on the branch and will never affect the production environment.

If you’d like to try Neon

today
DATE

, pop over here and sign up:

neon.tech
NORP

, you might also want to sneak a peak at our getting started guides:

(il)