With Apollo
Using pg_grapqhl with Apollo.
This guide will show you how to use pg_graphql with Apollo and GraphQL Code Generator for type-safe GraphQL queries in your React application.
Apollo Setup
Pre-requisites
- Follow the Apollo Getting Started Guide.
- Follow the GraphQL Code Generator Installation Guide.
Configuring GraphQL Code Generator
Modify your codegen.ts file to reflect the following:
1import type { CodegenConfig } from '@graphql-codegen/cli'2import { addTypenameSelectionDocumentTransform } from '@graphql-codegen/client-preset'34const config: CodegenConfig = {5 schema: 'http://localhost:54321/graphql/v1', // Using the local endpoint, update if needed6 documents: 'src/**/*.tsx',7 overwrite: true,8 ignoreNoDocuments: true,9 generates: {10 'src/gql/': {11 preset: 'client',12 documentTransforms: [addTypenameSelectionDocumentTransform],13 plugins: [],14 config: {15 scalars: {16 UUID: 'string',17 Date: 'string',18 Time: 'string',19 Datetime: 'string',20 JSON: 'string',21 BigInt: 'string',22 BigFloat: 'string',23 Opaque: 'any',24 },25 },26 },27 },28 hooks: {29 afterAllFileWrite: ['npm run prettier'], // optional30 },31}3233export default configConfiguring Apollo Client
This example uses Supabase for the GraphQL server, but pg_graphql can be used independently.
1import {2 ApolloClient,3 InMemoryCache,4 createHttpLink,5 defaultDataIdFromObject6} from '@apollo/client'7import { setContext } from '@apollo/client/link/context'8import { relayStylePagination } from '@apollo/client/utilities'9import supabase, { SUPABASE_ANON_KEY } from './supabase'1011const cache = new InMemoryCache({12 dataIdFromObject(responseObject) {13 if ('nodeId' in responseObject) {14 return `${responseObject.nodeId}`15 }1617 return defaultDataIdFromObject(responseObject)18 },19 possibleTypes: { Node: ['Todos'] }, // optional, but useful to specify supertype-subtype relationships20 typePolicies: {21 Query: {22 fields: {23 todosCollection: relayStylePagination(), // example of paginating a collection24 node: {25 read(_, { args, toReference }) {26 const ref = toReference({27 nodeId: args?.nodeId,28 })2930 return ref31 },32 },33 },34 },35 },36})3738const httpLink = createHttpLink({39 uri: 'http://localhost:54321/graphql/v1',40})4142const authLink = setContext(async (_, { headers }) => {43 const token = (await supabase.auth.getSession()).data.session?.access_token4445 return {46 headers: {47 ...headers,48 Authorization: token ? `Bearer ${token}` : '',49 apikey: SUPABASE_ANON_KEY,50 },51 }52})5354const apolloClient = new ApolloClient({55 link: authLink.concat(httpLink),56 cache,57})5859export default apolloClienttypePolicies.Query.fields.nodeis also optional, but useful for reducing cache misses. Learn more about Redirecting to cached data.
Example Query
1import { useQuery } from '@apollo/client'2import { graphql } from './gql'34const allTodosQueryDocument = graphql(/* GraphQL */ `5 query AllTodos($cursor: Cursor) {6 todosCollection(first: 10, after: $cursor) {7 edges {8 node {9 nodeId10 title11 }12 }13 pageInfo {14 endCursor15 hasNextPage16 }17 }18 }19`)2021const TodoList = () => {22 const { data, fetchMore } = useQuery(allTodosQueryDocument)2324 return (25 <>26 {data?.thingsCollection?.edges.map(({ node }) => (27 <Todo key={node.nodeId} title={node.title} />28 ))}29 {data?.thingsCollection?.pageInfo.hasNextPage && (30 <Button31 onClick={() => {32 fetchMore({33 variables: {34 cursor: data?.thingsCollection?.pageInfo.endCursor,35 },36 })37 }}38 >39 Load More40 </Button>41 )}42 </>43 )44}4546export default TodoList