PrismaでGraphQL APIを自動生成しよう - チュートリアル
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
#contents
* PrismaでGraphQL APIを自動生成しよう - チュートリアル [#...
** 1. はじめに [#yd10fc95]
このチュートリアルでは、Prismaのスキーマ定義から型安全なG...
*** 完成イメージ [#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...
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], refer...
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 --transpil...
"generate": "prisma generate"
}
}
** 5. 自動生成されたコードの確認 [#j890f2c7]
`npx prisma generate`を実行すると、`src/generated/type-gr...
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`のインポートを確認
終了行:
#contents
* PrismaでGraphQL APIを自動生成しよう - チュートリアル [#...
** 1. はじめに [#yd10fc95]
このチュートリアルでは、Prismaのスキーマ定義から型安全なG...
*** 完成イメージ [#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...
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], refer...
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 --transpil...
"generate": "prisma generate"
}
}
** 5. 自動生成されたコードの確認 [#j890f2c7]
`npx prisma generate`を実行すると、`src/generated/type-gr...
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`のインポートを確認
ページ名: