<!-- markdown -->
[TOC]
# PrismaでGraphQL APIを自動生成しよう - チュートリアル
## 1. はじめに
このチュートリアルでは、Prismaのスキーマ定義から型安全なGraphQL APIを自動生成する方法を学びます。
### 完成イメージ
- データベースのスキーマを定義するだけで、GraphQLのAPIが自動生成される
- TypeScriptの型定義も自動生成される
- CRUD操作用のリゾルバーが自動で実装される
### 前提条件
- Node.js(v16以上)
- npmまたはyarn
- コマンドラインの基本的な操作
## 2. プロジェクトのセットアップ
まずは必要なツールとライブラリをインストールします:
# プロジェクトの作成
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の設定
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. サーバーの実装
`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. 自動生成されたコードの確認
`npx prisma generate`を実行すると、`src/generated/type-graphql`ディレクトリに以下のファイルが生成されます:
src/generated/type-graphql/
├── enums/ # 列挙型の定義
├── models/ # モデルクラスの定義
├── resolvers/ # 自動生成されたリゾルバー
└── index.ts # エクスポート定義
生成されるリゾルバーの例:
- `createUser`
- `updateUser`
- `deleteUser`
- `users`(検索)
- `user`(1件取得)
- 同様のPost用リゾルバー
## 6. 動作確認
サーバーを起動:
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
}
}
}
## 7. 生成されたコードのカスタマイズ
自動生成されたコードに独自の機能を追加することもできます:
// 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. まとめ
- PrismaのスキーマからGraphQL APIを自動生成できた
- CRUDオペレーションが自動実装された
- 型安全性が確保された
- カスタムリゾルバーの追加も可能
## 次のステップ
- 認証/認可の実装
- バリデーションの追加
- テストの作成
- 本番環境へのデプロイ
## トラブルシューティング
よくある問題:
1. 型が生成されない
→ `npx prisma generate`を実行
2. デコレータエラー
→ `tsconfig.json`の設定を確認
3. 実行時エラー
→ `reflect-metadata`のインポートを確認