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:
_33import type { CodegenConfig } from '@graphql-codegen/cli'_33import { addTypenameSelectionDocumentTransform } from '@graphql-codegen/client-preset'_33_33const config: CodegenConfig = {_33 schema: 'http://localhost:54321/graphql/v1', // Using the local endpoint, update if needed_33 documents: 'src/**/*.tsx',_33 overwrite: true,_33 ignoreNoDocuments: true,_33 generates: {_33 'src/gql/': {_33 preset: 'client',_33 documentTransforms: [addTypenameSelectionDocumentTransform],_33 plugins: [],_33 config: {_33 scalars: {_33 UUID: 'string',_33 Date: 'string',_33 Time: 'string',_33 Datetime: 'string',_33 JSON: 'string',_33 BigInt: 'string',_33 BigFloat: 'string',_33 Opaque: 'any',_33 },_33 },_33 },_33 },_33 hooks: {_33 afterAllFileWrite: ['npm run prettier'], // optional_33 },_33}_33_33export default config
Configuring Apollo Client#
This example uses Supabase for the GraphQL server, but pg_graphql can be used independently.
_58import {_58 ApolloClient,_58 InMemoryCache,_58 createHttpLink,_58 defaultDataIdFromObject_58} from '@apollo/client'_58import { setContext } from '@apollo/client/link/context'_58import { relayStylePagination } from '@apollo/client/utilities'_58import supabase from './supabase'_58_58const cache = new InMemoryCache({_58 dataIdFromObject(responseObject) {_58 if ('nodeId' in responseObject) {_58 return `${responseObject.nodeId}`_58 }_58_58 return defaultDataIdFromObject(responseObject)_58 },_58 possibleTypes: { Node: ['Todos'] } // optional, but useful to specify supertype-subtype relationships_58 typePolicies: {_58 Query: {_58 fields: {_58 todosCollection: relayStylePagination(), // example of paginating a collection_58 node: {_58 read(_, { args, toReference }) {_58 const ref = toReference({_58 nodeId: args?.nodeId,_58 })_58_58 return ref_58 },_58 },_58 },_58 },_58 },_58})_58_58const httpLink = createHttpLink({_58 uri: 'http://localhost:54321/graphql/v1',_58})_58_58const authLink = setContext(async (_, { headers }) => {_58 const token = (await supabase.auth.getSession()).data.session?.access_token_58_58 return {_58 headers: {_58 ...headers,_58 Authorization: token ? `Bearer ${token}` : '',_58 },_58 }_58})_58_58const apolloClient = new ApolloClient({_58 link: authLink.concat(httpLink),_58 cache,_58})_58_58export default apolloClient
typePolicies.Query.fields.node
is also optional, but useful for reducing cache misses. Learn more about Redirecting to cached data.
Example Query#
_46import { useQuery } from '@apollo/client'_46import { graphql } from './gql'_46_46const allTodosQueryDocument = graphql(/* GraphQL */ `_46 query AllTodos($cursor: Cursor) {_46 todosCollection(first: 10, after: $cursor) {_46 edges {_46 node {_46 nodeId_46 title_46 }_46 }_46 pageInfo {_46 endCursor_46 hasNextPage_46 }_46 }_46 }_46`)_46_46const TodoList = () => {_46 const { data, fetchMore } = useQuery(allTodosQueryDocument)_46_46 return (_46 <>_46 {data?.thingsCollection?.edges.map(({ node }) => (_46 <Todo key={node.nodeId} title={node.title} />_46 ))}_46 {data?.thingsCollection?.pageInfo.hasNextPage && (_46 <Button_46 onClick={() => {_46 fetchMore({_46 variables: {_46 cursor: data?.thingsCollection?.pageInfo.endCursor,_46 },_46 })_46 }}_46 >_46 Load More_46 </Button>_46 )}_46 </>_46 )_46}_46_46export default TodoList