GraphQL Nexusは、JavaScript/TypeScript向けのコードファーストでタイプセーフなGraphQLスキーマ構築ライブラリです。Prismaクライアントと新しいnexus-prismaプラグインを使用して、どのようにデータベースに接続できるかをご覧ください。

⚠️ この記事は古くなっています。これは現在非推奨となっているPrisma 1に関するものです。Prismaの最新バージョンについては、ドキュメントをご覧ください。⚠️
まとめ: GraphQL Nexusによるコードファースト開発
前回の記事では、TypeScriptとJavaScript向けのコードファースト開発を可能にするGraphQLライブラリであるGraphQL Nexusを紹介しました。Nexusでは、GraphQLスキーマがプログラム的に定義され、実装されます。そのため、sangria-graphql(Scala)、graphlq-ruby、またはgraphene(Python)など、他の言語でのGraphQLサーバーの実績あるアプローチを踏襲しています。
本日の記事では、Prismaクライアントと新しいnexus-prismaプラグインを使用して、NexusベースのGraphQLサーバーをデータベースに接続する方法について説明します。後ほど、ブログアプリ向けのGraphQL APIをゼロから構築する実践的な例をご紹介します。
nexus-prismaはPostgreSQL、MySQL、MongoDBで動作します。詳細なドキュメントはこちらをご覧ください。
TLDR: nexus-prismaプラグインの利点
- GraphQLにおけるPrismaモデルのCRUD操作
- Prismaモデルのカスタマイズ(例: 特定のフィールドを非表示にする、計算フィールドを追加する)
- 完全なタイプセーフティ: GraphQLスキーマとデータベースのための整合性のある型セット
- GraphQLエコシステムとの互換性(例:
apollo-server、graphql-yoga、など)
nexus-prismaワークフローの理解
ORMの代替としてのPrismaクライアント
Prismaをこれまで使用したことがない方のために、その動作を簡単に説明します
- データモデルを定義するか、Prismaに既存のデータベースを内省させる
- Prismaクライアント(タイプセーフなデータベースクライアント)を生成する
- Prismaクライアントを使用して、アプリケーション(例: GraphQL API)でデータベースにアクセスする
nexus-prismaプラグインの内部動作
nexus-prismaを追加する場合、もう1つのステップがあります。nexus-prisma-generateコード生成CLIを呼び出すことです。これは、Prismaモデル向けの本格的なGraphQL CRUD APIの構成要素を生成します。例えば、Userモデルの場合、以下のものが含まれます
- クエリ
user(...): User!: 単一のレコードを取得するusers(...): [User!]!: レコードのリストを取得するusersConnection(...): UserConnection!: リレーコネクション & 集計
- ミューテーション
createUser(...): User!: 新しいレコードを作成するupdateUser(...): User: レコードを更新するdeleteUser(...): User: レコードを削除するupdatesManyUsers(...): BatchPayload!: 複数のレコードを一括で更新するdeleteManyUsers(...): BatchPayload!: 複数のレコードを一括で削除する
- GraphQL入力型
UserCreateInput: レコードのすべてのフィールドをラップするUserUpdateInput: レコードのすべてのフィールドをラップするUserWhereInput: レコードのすべてのフィールドのフィルターを提供するUserWhereUniqueInput: レコードの一意なフィールドのフィルターを提供するUserUpdateManyMutationInput: 一括更新が可能なフィールドをラップするUserOrderByInput: フィールドによる昇順または降順の並び順を指定する
UserCreateInputとUserUpdateInputは、リレーションフィールドの扱い方が異なります。
nexusとnexus-prismaでGraphQLサーバーコードを記述する際、これらの操作を公開し、自身のAPIニーズに合わせてカスタマイズすることで構築します。
CRUDの構成要素を生成した後、nexus-prismaのprismaObjectTypeを使用して、それらを公開(およびカスタマイズ)し始めることができます。以下のコードスニペットは、Prismaとnexus-prismaに基づいたTODOリストアプリ向けのGraphQL APIを提供する実装を示しています。
私たちはprismaObjectTypeをQueryとMutationに適用しています。Queryでは、すべてのフィールド(つまりtodo、todoes、todoesConnection)を保持しています。Mutationでは、公開される操作をカスタマイズするためにprismaFieldsを使用しています。
prismaFieldsは公開する操作を選択することを可能にします。このケースでは、モデルを作成する操作(createTodo)のみを保持したいと考えています。生成されたCRUD構成要素の中から、updateTodoもdeleteTodoも含まれていませんが、特定のTodoにチェックを入れる独自のmarkAsDone(id: ID!)ミューテーションを実装しています。
例: 標準CRUDからカスタマイズされたGraphQL APIへ
それでは、標準的なPrismaのユースケースを簡単に見て、ブログアプリ向けのGraphQL APIを数ステップで素早く構築する方法を確認しましょう。以下がその手順です
- TypeScriptを使用してPrismaプロジェクト(無料のデモデータベースを使用)をセットアップする
- モデルを定義し、データベースをマイグレートしてPrismaクライアントを生成する
nexus-prisma経由で完全なCRUD GraphQL APIを公開するnexus-prisma経由でGraphQL APIをカスタマイズする
一緒に作業を進めるには、Prisma CLIがインストールされている必要があります
1) TypeScript、nexus、nexus-prismaでPrismaプロジェクトをセットアップする
このセクションは主にプロジェクトのセットアップに関するものです。コードを一緒に書かない場合はスキップしても構いませんが、そうでない場合は以下のセクションを展開してください。
Prisma CLIを使用してシンプルなPrismaプロジェクトを作成する
対話型プロンプトで、以下のオプションを選択します
- ブラウザでPrisma Cloudと認証します(必要な場合)
- ターミナルに戻り、提案されたすべての値を確定します
- ブラウザでPrisma Cloudと認証します(必要な場合)
デモサーバーの代わりに、Dockerを使用してPrismaをローカルで実行することもできます。
次に、nexus-prismaワークフローを設定する必要があります。以下の依存関係を追加します(myblogディレクトリ内)
次に、以下の2行をprisma.ymlの末尾に追加します
これにより、モデルに変更を加えるたびに、Prismaクライアントと生成されたnexus-prismaのCRUD構成要素が確実に更新されます。
TypeScriptを使用しているため、手早くtsconfig.jsonを追加しましょう
最後に、開発に使用するstartスクリプトを追加します。これは、バックグラウンドでファイルを監視し、コードを記述するにつれて生成されたSDLとNexusの型定義を更新する開発サーバーを起動します。これをpackage.jsonに追加してください
2) モデルの定義、データベースのマイグレーション、Prismaクライアントの生成
prisma initコマンドは、datamodel.prismaにデフォルトのUserモデルを作成しました。ブログアプリケーションを構築するため、モデルをアプリケーションドメインに合わせて調整しましょう
次に、データモデルをデータベースに適用してマイグレートする必要があります。以下のコマンドを使用すると、datamodel.prismaで定義された各モデルが基盤となるデータベースのテーブルにマッピングされます
以前にprisma.ymlでpost-deployフックを設定したため、PrismaクライアントとCRUD構成要素は自動的に更新されます。
3) nexus-prisma経由で完全なCRUD GraphQL APIを公開する
プロジェクトの初期段階では、APIによって完全なCRUD機能が公開されていると役立つことがよくあります。より制約されたAPI要件は通常、時間とともに現れます。nexus-prismaは、完全なCRUDからカスタマイズされたAPI操作へ移行するための直接的なパスを提供することで、これを完全に考慮しています。
定義されたモデルに対して完全なCRUD(これにはフィルター、ページネーション、ソートが含まれます)を公開するGraphQL APIから始めましょう。index.tsという新しいファイルを作成し、以下のコードを追加してください
この短いチュートリアルではファイル構造にあまり注意を払っていません。適切なセットアップとモジュール化されたスキーマについては、
graphql-authの例を確認してください。
npm run startを実行した後、https://:4000でGraphQLサーバーのGraphQL Playgroundを開くことができます。上記で書いたわずかなコードで、すでに本格的なGraphQL CRUD APIが利用可能です。
これはどのように機能するのでしょうか? nexus-prisma-generateは、Prismaモデル(あなたのCRUD構成要素)向けのCRUD APIを提供するGraphQLスキーマを生成しました。このGraphQLスキーマはOpenCRUD仕様に準拠しています。prismaObjectType関数を使用すると、そのスキーマの操作を公開およびカスタマイズできます。
prismaObjectTypeとprismaFieldsはホワイトリスト方式を採用しており、公開したいフィールドを明示的にリストアップする必要があります。ワイルドカード演算子*はすべてのフィールドを含みます。
4) nexus-prisma経由でGraphQL APIをカスタマイズする
このセクションでは、nexus-prismaからのCRUD GraphQL APIをカスタマイズする方法を学びます。具体的には、以下のことを行います。
Userモデルからフィールドを隠すPostモデルに計算フィールドを追加するcreatePostとupdatePostミューテーションを隠す- 2つのカスタム
createDraftとpublishミューテーションを追加する
4.1) Userモデルからフィールドを隠す
このセクションでは、Userモデルからemailフィールドを隠します。
モデルをカスタマイズするには、prismaObjectType関数を適用し、definition(t)関数をオプションとして渡す必要があります。
モデルtに対してprismaFieldsを呼び出すことで、公開されるフィールド(およびその引数)をカスタマイズできます。emailがリストに含まれていないため、GraphQL APIから削除されます。
変更を適用するには、makePrismaSchema内のtypes配列にUserを明示的に渡す必要があります。
エディターが、生成されたCRUD構成要素に基づいて、prismaObjectTypeとprismaFieldsに何を渡すべきか提案できることに注意してください。つまり、prismaObjectType('')と入力してCtrl+Spaceを押すと、生成されたすべてのCRUD構成要素の名前が提案されます。t.prismaFields([''])を呼び出すと、tのフィールドが提案されます。
4.2) Postモデルに計算フィールドを追加する
nexus-prismaによる新しいコードファーストアプローチでは、Prismaモデルに計算フィールドを簡単に追加することもできます。例えば、titleを常にすべて大文字で返すフィールドをPostに追加したいとします。その実装方法は以下の通りです。
私たちはgraphql-nexusから提供されるt.string(...) APIを使用して、モデルに新しいフィールドを追加します。これは計算フィールドであるため(したがってnexus-prismaによって自動的に解決されることはありません)、これにリゾルバーをアタッチする必要もあります。
これまでと同様に、カスタマイズされたPostモデルをtypes配列に明示的に追加する必要があります。
4.3) createPostとupdatePostミューテーションを隠す
Userモデルからemailフィールドを隠したのと同じ方法で、生成されたnexus-prisma CRUD構成要素の一部であるQuery/Mutation型から操作を隠すこともできます。
createPostとupdatePostを隠すには、再度definition(t)をオプションとしてprismaObjectTypeに渡す必要があります。型に対してprismaFieldsを呼び出した場合、保持したいすべてのフィールドを明示的にリストアップする必要があることに注意してください(空の配列は「操作を何も保持しない」と解釈されます)。
生成されたCRUD GraphQL APIには、バッチ処理とUPSERT操作も含まれていますが、ここでは簡潔にするためにそれらも除外しています。
4. 2つのカスタムcreateDraftとpublishミューテーションを追加する
最後に、GraphQL APIに2つのカスタムミューテーションを追加します。それらのSDL定義は以下のようになります
これらのミューテーションを実装するには、Mutation型に2つのフィールド(nexus APIのt.field( ... )を呼び出して)を追加する必要があります。
これを機能させるには、nexusパッケージからstringArgとidArgをインポートしてください。
GraphQL Nexusは、GraphQLスキーマのSDLバージョンも生成します。これは./generated/schema.graphqlで見つかります。GraphQL APIの最終バージョンは以下のようになります
コードファーストGraphQL記事からの3つの重要なポイント
これで、コードファーストGraphQLサーバー開発に関する記事シリーズは最終回となります。
GraphQL Nexusとnexus-prismaプラグインは、2年以上にわたるGraphQLエコシステムへの積極的な貢献から得た教訓を実装しています。SDLファーストのアプローチではあまりにも多くの問題が見つかったため、現在登場している新しいコードファーストのツールに非常に興奮しています。
私たちは、GraphQL Nexus(およびTypeGraphQLなどの他のコードファーストアプローチ)が、将来のGraphQLスキーマの構築方法を劇的に変えると強く信じています。
このシリーズからの主要なポイントは以下の通りです
- コードファーストアプローチは、追加のツールを必要とせず(「必要なツールはプログラミング言語だけ」)、SDLをコミュニケーションツールとしての利点を維持しつつ、言語の慣用的な方法でGraphQLサーバーを構築することを可能にします。
- GraphQL Nexusは、開発者が柔軟でタイプセーフなAPIでスキーマを構築できるようにします。自動補完とビルド時エラーチェックのおかげで、開発者は素晴らしい体験を得られます。
nexus-prismaプラグインはPrismaモデルの上に構築されており、開発者が自動生成されたCRUD構成要素を公開およびカスタマイズすることでGraphQL APIを構築できるようにします。
今すぐnexus-prismaを試してみましょう 🙌
nexus-prismaを試す方法はいくつかあります。ドキュメントのGetting Startedセクションに従うか、TypeScript GraphQLの例を探索することができます。
GitHub issueを開くか、Slackで連絡することで、フィードバックを共有してください。
nexus-prismaプラグインにおける素晴らしい仕事をしてくれた、私たちのオープンソースエンジニアFlavian Desverneに心から感謝します💪✨
次回の投稿をお見逃しなく!
Prismaニュースレターに登録する