Nx Nestjs Mongodb Mongoose統合のセットアップ - 第3部

Nx Nest.js GraphQL統合の第3部です。パッケージのインストール、設定の更新、GraphQLクライアントの生成を通じてシームレスな統合を行い、データ管理とスケーラビリティを高めます。Nx、Nest.js、GraphQLの統合ガイドの完成、おめでとうございます!今後のチュートリアルもお楽しみに。

技術公開日 更新日 読了目安 2 分

はじめに

Nx Nest.js GraphQL Integrationシリーズの第3部です。ここでは、プロジェクトにGraphQLを組み込んで強化していきます。以下の手順に沿って、必要なパッケージのインストール、app.module.tsファイルの更新、data-access-graphqlプロジェクトの生成、GraphQLコード生成の活用をシームレスに行っていきましょう。GraphQLクライアントの作成方法と、それをNext.js Webアプリケーションで利用する方法についても解説します。

参考URL

Engilaboo Next.js GraphQL Tutorial

パッケージのインストール

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

Nest.jsプロジェクトのapp.module.tsを更新

以下のコードを追加します:

@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')
    }),

これにより、APIをビルドした後、dist/apps/apiフォルダにautogenerated-schema.gqlが作成されます。

data-access-graphqlプロジェクトの生成

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

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;

Codegenの実行

package.jsonにスクリプトを追加します

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

Web用クライアントの作成

  1. apollo-client.tsを作成

apps/web/lib/apollo-client.ts

このケースでは、apps/webはNext.jsプロジェクトです。

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'
});
  1. 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;
  1. tsconfig.base.jsonを更新
    "paths": {
      "@/lib/*": [
        "apps/web/lib/*"
      ],
  1. 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>
  );
}

graphqlの利用

例:

  1. graphqlファイルの作成

todo.graphql

query getSampleTodos {
  sampleTodos {
    _id
    content
    editing
    completed
  }
}
  1. 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>;
}

おめでとうございます!Nx、Nest.js、GraphQLを見事に統合できました。このシリーズを通じて、データを効率的に管理・クエリできるようになり、アプリケーションはより堅牢でスケーラブルになりました。今後の役立つチュートリアルもお楽しみに!

第1部はこちらです。

Nx Nestjs Mongodb Mongoose統合のセットアップ - 第1部