## Introduction

Welcome to the third part of our Nx Nest.js GraphQL Integration series, where we enhance our project by incorporating GraphQL. Follow these steps to seamlessly install essential packages, update the `app.module.ts` file, generate the `data-access-graphql` project, and utilize GraphQL code generation. We'll guide you through creating a GraphQL client and demonstrate its usage in a Next.js web application.

## Reference URL

[Engilaboo Next.js GraphQL Tutorial](https://www.engilaboo.com/nextjs-graphql/)

## Install Packages

```bash
npm i @graphql-codegen/typed-document-node @graphql-codegen/cli @graphql-codegen/typescript-operations @apollo/client @graphql-codegen/client-preset
```

## Update app.module.ts in Nest.js Project

Add the following code:

```typescript
@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'web/.next'),
      exclude: ['/api/*', '/api/graphql']
    }),
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      path: '/api/graphql',
      autoSchemaFile: path.join(__dirname, './autogenerated-schema.gql')
    }),
```

By doing so, the `autogenerated-schema.gql` is created in the `dist/apps/api` folder after building the API.

## Generate data-access-graphql Project

```bash
npx nx generate @nx/js:library data-access-graphql --directory=libs/web/data-access-graphql --importPath=@libs/web/data-access-graphql --tags=scope:web --bundler=swc

✔ Which unit test runner would you like to use? · none
```

## Create codegen.yml

`tools/graphql-codegen/codegen.ts`

```ts
import type { CodegenConfig } from '@graphql-codegen/cli';

const codegenConfig: CodegenConfig = {
  overwrite: true,
  schema: 'dist/apps/api/autogenerated-schema.gql',
  documents: ['apps/web/**/*.graphql', 'libs/**/*.graphql'],
  generates: {
    'libs/web/data-access-graphql/src/lib/__generated__/': {
      preset: 'client',
      plugins: [
        {
          // branded type for custom Scalar
          add: {
            content: `export type DateString = string & { readonly __brand: unique symbol }`
          }
        }
      ],
      config: {
        strictScalars: true,
        useTypeImports: true,
        skipTypename: true,
        arrayInputCoercion: true,
        avoidOptionals: {
          field: true,
          inputValue: false,
          object: true,
          defaultValue: false
        },
        scalars: {
          Date: 'DateString'
        },
        enumsAsTypes: true
      }
    }
  }
};

export default codegenConfig;
```

## Run Codegen

Add script to package.json

```json
   "scripts": {
    "start:gql:watch": "graphql-codegen --config tools/graphql-codegen/codegen.ts --watch",
```

## Create Client for Web

1. Create apollo-client.ts

`apps/web/lib/apollo-client.ts`

> In this case, `apps/web` is a Next.js project.

```typescript
import { NEXT_PUBLIC_API_GQL_URL } from '@/config/index';
import { ApolloClient, InMemoryCache } from '@apollo/client';

// If env.NEXT_PUBLIC_API_GQL_URL is undefined, throw exeption.
if (!NEXT_PUBLIC_API_GQL_URL) {
  throw new Error('NEXT_PUBLIC_API_GQL_URL is undefined');
}

export const apolloClient = new ApolloClient({
  uri: NEXT_PUBLIC_API_GQL_URL,
  cache: new InMemoryCache(),
  credentials: 'include'
});
```

2. Create ApolloProvider

`apps/web/lib/apollo-client.ts`

```typescript
'use client';

import { apolloClient } from '@/lib/apollo-client';
import { ApolloProvider as Apollo } from '@apollo/client';

const ApolloProvider = ({ children }: React.PropsWithChildren) => {
  return <Apollo client={apolloClient}>{children}</Apollo>;
};

export default ApolloProvider;
```

3. Update `tsconfig.base.json`

```json
    "paths": {
      "@/lib/*": [
        "apps/web/lib/*"
      ],
```

4. Set ApolloProvider

`apps/web/app/layout.tsx`

```tsx
import ApolloProvider from '@/components/providers/ApolloProvider';
...

export default async function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html suppressHydrationWarning>
      <head>
        ...
      </head>

      <body className="overflow-x-hidden bg-white text-black antialiased dark:bg-gray-900 dark:text-white">
        <ApolloProvider>
          ...
        </ApolloProvider>
      </body>
    </html>
  );
}
```

## Use graphql

Example:

1. Create graphql file

`todo.graphql`

```graphql
query getSampleTodos {
  sampleTodos {
    _id
    content
    editing
    completed
  }
}
```

2. Use useQuery

```tsx
import { useQuery } from '@apollo/client';
import { GetSampleTodosDocument } from '@libs/web/data-access-graphql';

export default async function page() {
  const { data, loading, error } = useQuery(GetSampleTodosDocument);

  return <div>{data.GetSampleTodosDocument.map((x) => x._id)}</div>;
}
```

Congratulations! You've successfully configured Nx, Nest.js, and GraphQL in a harmonious integration. This series has empowered you to efficiently manage and query data, making your application more robust and scalable. Stay tuned for more insightful tutorials and happy coding!

The first part is here.

[Setting Up Nx Nestjs Mongodb Mongoose Integration - Part 1](/plants/nx-nestjs-mongodb-mongoose-part-1)
