#contents
* PrismaでGraphQL APIを自動生成しよう - チュートリアル [#idad4c92]

** 1. はじめに [#yd10fc95]

このチュートリアルでは、Prismaのスキーマ定義から型安全なGraphQL APIを自動生成する方法を学びます。

*** 完成イメージ [#uc6fdc64]
- データベースのスキーマを定義するだけで、GraphQLのAPIが自動生成される
- TypeScriptの型定義も自動生成される
- CRUD操作用のリゾルバーが自動で実装される

*** 前提条件 [#q05cf605]
- Node.js(v16以上)
- npmまたはyarn
- コマンドラインの基本的な操作

** 2. プロジェクトのセットアップ [#zd4ae878]

まずは必要なツールとライブラリをインストールします:

 # プロジェクトの作成
 mkdir prisma-graphql-generator
 cd prisma-graphql-generator
 
 # package.jsonの初期化
 npm init -y
 
 # 必要なパッケージのインストール
 npm install @prisma/client apollo-server graphql
 npm install -D prisma typescript ts-node-dev @types/node typegraphql-prisma type-graphql reflect-metadata

TypeScriptの設定ファイルを作成:

 # TypeScript設定ファイルの生成
 npx tsc --init

`tsconfig.json`を以下のように編集:

 {
   "compilerOptions": {
     "target": "es2018",
     "module": "commonjs",
     "lib": ["es2018", "esnext.asynciterable"],
     "experimentalDecorators": true,
     "emitDecoratorMetadata": true,
     "strictPropertyInitialization": false,
     "skipLibCheck": true,
     "esModuleInterop": true,
     "strict": true,
     "outDir": "./dist"
   }
 }

** 3. Prismaの設定 [#m6b57109]

Prismaを初期化し、スキーマを定義します:

 # Prismaの初期化
 npx prisma init

`prisma/schema.prisma`を以下のように編集:

 datasource db {
   provider = "sqlite"
   url      = "file:./dev.db"
 }
 
 generator client {
   provider = "prisma-client-js"
 }
 
 // ここが重要: GraphQL型の自動生成設定
 generator typegraphql {
   provider = "typegraphql-prisma"
   output   = "../src/generated/type-graphql"
 }
 
 // データモデルの定義
 model User {
   id        Int       @id @default(autoincrement())
   email     String    @unique
   name      String
   posts     Post[]
   createdAt DateTime  @default(now())
 }
 
 model Post {
   id        Int      @id @default(autoincrement())
   title     String
   content   String
   published Boolean  @default(false)
   author    User     @relation(fields: [authorId], references: [id])
   authorId  Int
   createdAt DateTime @default(now())
 }

データベースの準備:

 # マイグレーションの実行
 npx prisma migrate dev --name init
 
 # GraphQL型の生成
 npx prisma generate

** 4. サーバーの実装 [#ifd829d7]

`src/index.ts`を作成:

 import 'reflect-metadata';
 import { PrismaClient } from '@prisma/client';
 import { ApolloServer } from 'apollo-server';
 import { buildSchema } from 'type-graphql';
 import { resolvers } from './generated/type-graphql';
 
 async function main() {
   const prisma = new PrismaClient();
 
   // 自動生成されたリゾルバーを使用してスキーマを構築
   const schema = await buildSchema({
     resolvers,
     validate: false,
   });
 
   // Apollo Serverの設定
   const server = new ApolloServer({
     schema,
     context: () => ({ prisma }),
   });
 
   // サーバーの起動
   const { url } = await server.listen(4000);
   console.log(`🚀 Server ready at ${url}`);
 }
 
 main().catch(console.error);

`package.json`にスクリプトを追加:

 {
   "scripts": {
     "dev": "ts-node-dev --no-notify --respawn --transpile-only src/index.ts",
     "generate": "prisma generate"
   }
 }

** 5. 自動生成されたコードの確認 [#j890f2c7]

`npx prisma generate`を実行すると、`src/generated/type-graphql`ディレクトリに以下のファイルが生成されます:

 src/generated/type-graphql/
 ├── enums/          # 列挙型の定義
 ├── models/         # モデルクラスの定義
 ├── resolvers/      # 自動生成されたリゾルバー
 └── index.ts        # エクスポート定義

生成されるリゾルバーの例:
- `createUser`
- `updateUser`
- `deleteUser`
- `users`(検索)
- `user`(1件取得)
- 同様のPost用リゾルバー

** 6. 動作確認 [#i526c9a8]

サーバーを起動:
 npm run dev

ブラウザで `http://localhost:4000` にアクセスし、以下のクエリを試してみましょう:

*** ユーザーの作成: [#y3f62b95]
 mutation {
   createUser(data: {
     email: "test@example.com"
     name: "Test User"
   }) {
     id
     email
     name
   }
 }

*** 投稿の作成: [#n2ca1165]
 mutation {
   createPost(data: {
     title: "First Post"
     content: "Hello, World!"
     published: true
     author: {
       connect: { id: 1 }
     }
   }) {
     id
     title
     author {
       name
     }
   }
 }

*** データの取得: [#xd77bfc7]
 query {
   users {
     id
     name
     posts {
       title
       content
       published
     }
   }
 }

** 7. 生成されたコードのカスタマイズ [#l5ef2fb9]

自動生成されたコードに独自の機能を追加することもできます:

 // src/resolvers/CustomUserResolver.ts
 import { Resolver, Query, Ctx } from 'type-graphql';
 import { User } from '../generated/type-graphql';
 
 @Resolver(User)
 export class CustomUserResolver {
   @Query(returns => [User])
   async activeUsers(@Ctx() ctx: any) {
     return ctx.prisma.user.findMany({
       where: {
         posts: {
           some: {
             published: true
           }
         }
       }
     });
   }
 }

** 8. まとめ [#y225eadb]

- PrismaのスキーマからGraphQL APIを自動生成できた
- CRUDオペレーションが自動実装された
- 型安全性が確保された
- カスタムリゾルバーの追加も可能

** 次のステップ [#ke760352]
- 認証/認可の実装
- バリデーションの追加
- テストの作成
- 本番環境へのデプロイ

** トラブルシューティング [#h42b6f7f]

よくある問題:
1. 型が生成されない

   → `npx prisma generate`を実行

2. デコレータエラー

   → `tsconfig.json`の設定を確認

3. 実行時エラー

   → `reflect-metadata`のインポートを確認
トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS