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
Install Packages
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:
@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
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
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
"scripts": {
"start:gql:watch": "graphql-codegen --config tools/graphql-codegen/codegen.ts --watch",
Create Client for Web
- Create apollo-client.ts
apps/web/lib/apollo-client.ts
In this case,
apps/web
is a Next.js project.
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'
});
- Create ApolloProvider
apps/web/lib/apollo-client.ts
'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;
- Update
tsconfig.base.json
"paths": {
"@/lib/*": [
"apps/web/lib/*"
],
- Set ApolloProvider
apps/web/app/layout.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:
- Create graphql file
todo.graphql
query getSampleTodos {
sampleTodos {
_id
content
editing
completed
}
}
- Use useQuery
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.