このチュートリアルでは、Prismaのスキーマ定義から型安全なGraphQL APIを自動生成する方法を学びます。
まずは必要なツールとライブラリをインストールします:
# プロジェクトの作成 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" } }
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
`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" } }
`npx prisma generate`を実行すると、`src/generated/type-graphql`ディレクトリに以下のファイルが生成されます:
src/generated/type-graphql/ ├── enums/ # 列挙型の定義 ├── models/ # モデルクラスの定義 ├── resolvers/ # 自動生成されたリゾルバー └── index.ts # エクスポート定義
生成されるリゾルバーの例:
サーバーを起動:
npm run dev
ブラウザで `http://localhost:4000` にアクセスし、以下のクエリを試してみましょう:
mutation { createUser(data: { email: "test@example.com" name: "Test User" }) { id email name } }
mutation { createPost(data: { title: "First Post" content: "Hello, World!" published: true author: { connect: { id: 1 } } }) { id title author { name } } }
query { users { id name posts { title content published } } }
自動生成されたコードに独自の機能を追加することもできます:
// 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 } } } }); } }
よくある問題: 1. 型が生成されない
→ `npx prisma generate`を実行
2. デコレータエラー
→ `tsconfig.json`の設定を確認
3. 実行時エラー
→ `reflect-metadata`のインポートを確認