This guide was contributed by Josep Vidal from Grafbase
Grafbase allows you to combine your data sources into a centralized GraphQL endpoint and deploy a serverless GraphQL backend.
This guide describes how to create a GraphQL API using Grafbase and use Grafbase Edge Resolvers with the Neon serverless driver to interact with your Neon database at the edge.
The example project in this guide simulates a marketplace of products, where the product price is dynamically calculated based on data retrieved from your Neon database.
Prerequisites
- The Grafbase CLI
- A Neon project. See Create a Neon project.
Create a backend with Grafbase
- 
Create a directory and initialize your Grafbase project by running the following commands: npx grafbase init grafbase-neon cd grafbase-neon
- 
In your project directory, open the grafbase/schema.graphqlfile and replace the existing content with the following schema:extend type Mutation { addProductVisit(productId: ID!): ID! @resolver(name: "add-product-visit") } type Product @model { name: String! price: Float @resolver(name: "product/price") }
Create the schema in Neon
- 
Navigate to the Neon Console and select your project. 
- 
Open the Neon SQL Editor and run the following CREATE TABLEstatement:CREATE TABLE product_visits(id SERIAL PRIMARY KEY, product_id TEXT NOT NULL);The product_visitstable stores product page view data that the application uses to dynamically calculate a product price.
Create the resolver files
The schema includes an addProductVisit query and prodcut/price field. Create resolvers for those by creating the following files in your project directory:
- grafbase/resolvers/add-product-visit.js
- grafbase/resolvers/product/price.js
You can use the following commands to create the files:
cd grafbase
mkdir resolvers
cd resolvers
touch add-product-visit.js
mkdir product
cd product
touch price.jsYou will add code to these files in a later step.
Install the Neon serverless driver
Inside the grafbase directory in your project, run the following commands to install the Neon serverless driver:
cd ..
npm init -y
npm install @neondatabase/serverlessRetrieve your Neon connection string
A database connection string is required to forward queries to your Neon database. You can find your database connection string by clicking the Connect button on your Project Dashboard.
- 
Navigate to the Neon Project Dashboard. 
- 
Click Connect and copy the connection string for your database. The connection string should appear similar to the following: postgresql://[user]:[password]@[neon_hostname]/[dbname]
- 
Add a DATABASE_URLenvironment variable to yourgrafbase/.envfile and set the value to your connection string. For example:DATABASE_URL=postgresql://[user]:[password]@[neon_hostname]/[dbname]
Add code to the resolvers
- 
In the resolvers/product/add-product-visitresolver, add the following code, which inserts a new record in theproduct_visitstable with aproductIdeach time the resolver is queried.# grafbase/resolvers/add-product-visit.js import { Client } from '@neondatabase/serverless' export default async function Resolver(_, { productId }) { const client = new Client(process.env.DATABASE_URL) await client.connect() await client.query( `INSERT INTO product_visits (product_id) VALUES ('${productId}')` ) await client.end() return productId }
- 
In the grafbase/resolvers/product/price.jsresolver, add the following code, which calculates the product price based on the number of product visits (the number of visits represents customer interest in the product).# grafbase/resolvers/product/price.js import { Client } from '@neondatabase/serverless' export default async function Resolver({ id }) { const client = new Client(process.env.DATABASE_URL) await client.connect() const { rows: [{ count }] } = await client.query( `SELECT COUNT(*) FROM product_visits WHERE product_id = '${id}'` ) await client.end() return Number.parseInt(count) }
Test the resolvers
To test the resolvers with Neon, perform the following steps:
- 
Start the Grafbase CLI: npx grafbase dev
- 
Go to http://localhost:4000 and execute the following GraphQL mutation, which creates a new product: mutation { productCreate(input: { name: "Super Product" }) { product { id name } } }
- 
Use the product idto execute the following mutation, which adds a row to the database table in Neon:mutation { addProductVisit(productId: "PREVIOUS_PRODUCT_ID") }
- 
Query the same product, and check the price: query { product(input: { by: "PREVIOUS_PRODUCT_ID" }) { id name price } }
- 
Run the query several more times and watch how the price increases as "interest" in the product increases.