diff --git a/docs/usage_with_apollo.md b/docs/usage_with_apollo.md new file mode 100644 index 00000000..f1a8edbf --- /dev/null +++ b/docs/usage_with_apollo.md @@ -0,0 +1,166 @@ +This guide will show you how to use pg_graphql with [Apollo](https://www.apollographql.com/docs/react/) and [GraphQL Code Generator](https://the-guild.dev/graphql/codegen) for type-safe GraphQL queries in your React application. + +## Apollo Setup + +### Pre-requisites + +1. Follow the [Apollo Getting Started Guide](https://www.apollographql.com/docs/react/get-started). +2. Follow the [GraphQL Code Generator Installation Guide](https://the-guild.dev/graphql/codegen/docs/getting-started/installation). + +### Configuring GraphQL Code Generator + +Modify your `codegen.ts` file to reflect the following: + +```javascript +import type { CodegenConfig } from '@graphql-codegen/cli' +import { addTypenameSelectionDocumentTransform } from '@graphql-codegen/client-preset' + +const config: CodegenConfig = { + schema: 'http://localhost:54321/graphql/v1', // Using the local endpoint, update if needed + documents: 'src/**/*.tsx', + overwrite: true, + ignoreNoDocuments: true, + generates: { + 'src/gql/': { + preset: 'client', + documentTransforms: [addTypenameSelectionDocumentTransform], + plugins: [], + config: { + scalars: { + UUID: 'string', + Date: 'string', + Time: 'string', + Datetime: 'string', + JSON: 'string', + BigInt: 'string', + BigFloat: 'string', + Opaque: 'any', + }, + }, + }, + }, + hooks: { + afterAllFileWrite: ['npm run prettier'], // optional + }, +} + +export default config +``` + +### Configuring Apollo Client + +This example uses [Supabase](https://supabase.com) for the GraphQL server, but pg_graphql can be used independently. + +```typescript +import { + ApolloClient, + InMemoryCache, + createHttpLink, + defaultDataIdFromObject +} from '@apollo/client' +import { setContext } from '@apollo/client/link/context' +import { relayStylePagination } from '@apollo/client/utilities' +import supabase from './supabase' + +const cache = new InMemoryCache({ + dataIdFromObject(responseObject) { + if ('nodeId' in responseObject) { + return `${responseObject.nodeId}` + } + + return defaultDataIdFromObject(responseObject) + }, + possibleTypes: { Node: ['Todos'] } // optional, but useful to specify supertype-subtype relationships + typePolicies: { + Query: { + fields: { + todosCollection: relayStylePagination(), // example of paginating a collection + node: { + read(_, { args, toReference }) { + const ref = toReference({ + nodeId: args?.nodeId, + }) + + return ref + }, + }, + }, + }, + }, +}) + +const httpLink = createHttpLink({ + uri: 'http://localhost:54321/graphql/v1', +}) + +const authLink = setContext(async (_, { headers }) => { + const token = (await supabase.auth.getSession()).data.session?.access_token + + return { + headers: { + ...headers, + Authorization: token ? `Bearer ${token}` : '', + }, + } +}) + +const apolloClient = new ApolloClient({ + link: authLink.concat(httpLink), + cache, +}) + +export default apolloClient +``` + +- `typePolicies.Query.fields.node` is also optional, but useful for reducing cache misses. Learn more about [Redirecting to cached data](https://www.apollographql.com/docs/react/performance/performance#redirecting-to-cached-data). + +## Example Query + +```javascript +import { useQuery } from '@apollo/client' +import { graphql } from './gql' + +const allTodosQueryDocument = graphql(/* GraphQL */ ` + query AllTodos($cursor: Cursor) { + todosCollection(first: 10, after: $cursor) { + edges { + node { + nodeId + title + } + } + pageInfo { + endCursor + hasNextPage + } + } + } +`) + +const TodoList = () => { + const { data, fetchMore } = useQuery(allTodosQueryDocument) + + return ( + <> + {data?.thingsCollection?.edges.map(({ node }) => ( + + ))} + {data?.thingsCollection?.pageInfo.hasNextPage && ( + + )} + + ) +} + +export default TodoList +``` diff --git a/mkdocs.yaml b/mkdocs.yaml index ccbc9e86..245aec54 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -17,6 +17,7 @@ nav: - Configuration: 'configuration.md' - Guides: - Supabase: 'supabase.md' + - Usage with Apollo: 'usage_with_apollo.md' - Usage with Relay: 'usage_with_relay.md' - Example Schema: 'example_schema.md' - Installation: 'installation.md'