With Relay
Using pg_grapqhl with Relay.
pg_graphql implements the GraphQL Global Object Identification Specification (Node
interface) and the GraphQL Cursor Connections Specification to be compatible with Relay.
Follow the Relay Installation Guide.
Modify your relay.config.js
file to reflect the following:
// standard relay config options
schema: './data/schema.graphql',
exclude: ['**/node_modules/**', '**/__mocks__/**', '**/__generated__/**'],
// pg_graphql specific options
nodeInterfaceIdField: 'nodeId',
nodeInterfaceIdVariableName: 'nodeId',
schemaConfig
tells the Relay compiler where to find the nodeId
field on the node
interface
customScalarTypes
will improve Relay's type emission
For Relay versions older than v16.2.0, it should be named customScalars
instead.
This example uses Supabase for the GraphQL server, but pg_graphql can be used independently.
import supabase, { SUPABASE_ANON_KEY, SUPABASE_URL } from './supabase'
const fetchQuery: FetchFunction = async (operation, variables) => {
} = await supabase.auth.getSession()
const response = await fetch(`${SUPABASE_URL}/graphql/v1`, {
'Content-Type': 'application/json',
apikey: SUPABASE_ANON_KEY,
Authorization: `Bearer ${session?.access_token ?? SUPABASE_ANON_KEY}`,
return await response.json()
const network = Network.create(fetchQuery)
const store = new Store(new RecordSource())
const environment = new Environment({
getDataID: (node) => node.nodeId,
handle(field, _record, argValues) {
if (field.name === 'node' && 'nodeId' in argValues) {
// If field is node(nodeId: $nodeId), look up the record by the value of $nodeId
export default environment
getDataID
is the most important option to add, as it tells Relay how to store data correctly in the cache.
missingFieldHandlers
is optional in this example but helps with Rendering Partially Cached Data.
Say you are working on a Todo app and want to add pagination. You can use @connection
and @prependNode
to do this.
Fragment passed to usePaginationFragment()
fragment TodoList_query on Query
cursor: { type: "Cursor" }
count: { type: "Int", defaultValue: 20 }
@refetchable(queryName: "TodoListPaginationQuery") {
todosCollection(after: $cursor, first: $count)
@connection(key: "TodoList_query_todosCollection") {
Mutation to create a new Todo
mutation TodoCreateMutation($input: TodosInsertInput!, $connections: [ID!]!) {
insertIntoTodosCollection(objects: [$input]) {
records @prependNode(connections: $connections, edgeTypeName: "TodosEdge") {
Code to call the mutation
import { ConnectionHandler, graphql, useMutation } from 'react-relay'
// inside a React component
const [todoCreateMutate, isMutationInFlight] =
useMutation<TodoCreateMutation>(CreateTodoMutation)
// inside your create todo function
const connectionID = ConnectionHandler.getConnectionID(
'TodoList_query_todosCollection'
connections: [connectionID],