はじめに
最近GraphQLについて学びまして、
Next.js + GraphQL + GraphQL CodeGenerator + Prismaの構成でTodoアプリを構築したので
解説をしつつ、その記録をここに残します。
環境
- Macbook Air
- node
- v18.13.0
- pnpm
- 7.27.0
目次
-
前編 👈 今ここ
- Next Create App
- GraphQLサーバー構築
- Subscription
- DB・Prisma
-
中編
- GraphQL Schema
- GraphQL Context
- GraphQL Code Generator
- GraphQL Resolver
- GraphQLサーバー修正
-
後編
- フロント側準備
- フロント側実装
前編
前編は準備フェーズです。
1. Next Create App
-
create app
$ pnpm create next-app nextjs-sample-graphql --typescript # ESLintを使うかどうか・・・Yes ✔ Would you like to use ESLint with this project? … Yes # TailwindCSSを使うかどうか・・・Yes ✔ Would you like to use Tailwind CSS with this project? … Yes # srcディレクトリを使うかどうか・・・Yes ✔ Would you like to use `src/` directory with this project? … Yes # appディレクトリを使うかどうか・・・No ✔ Would you like to use experimental `app/` directory with this project? … No # エイリアス設定・・・@/* ✔ What import alias would you like configured? … @/* $ cd nextjs-sample-graphql $ pnpm run dev
localhost:3000でサーバーが起動します。
2. GraphQLサーバー構築
-
install
$ pnpm add graphql graphql-yoga
-
GraphQL Server on
api/graphql.ts
src/pages/api/graphql.tsimport { createYoga, createSchema } from 'graphql-yoga' import type { NextApiRequest, NextApiResponse } from 'next' import { YogaSchemaDefinition } from 'graphql-yoga/typings/plugins/useSchema'; export const config = { api: { bodyParser: false } } const schema = createSchema({ typeDefs: /* GraphQL */ ` type Query { greetings: String } `, resolvers: { Query: { greetings: () => 'This is the `greetings` field of the root `Query` type' } } }) as YogaSchemaDefinition<{ req: NextApiRequest; res: NextApiResponse; }> export default createYoga<{ req: NextApiRequest res: NextApiResponse }>({ schema, graphqlEndpoint: '/api/graphql' })
YogaGraphQLサーバーが立ち上がっています。
試しにQueryを叩いてみます。ちゃんと叩けました👍
3. Subscription
Next.jsのAPIルートではWebSocketsを使うことができません。GraphQL API、WebSocket、および残りの Next.js コンテンツを使うためには、Next.jsカスタムサーバーを作成する必要があります。
引用: WebSockets cannot be used with Next.js API Routes(opens in a new tab), we therefore have to create a custom Next.js server(opens in a new tab) that will serve the GraphQL API, WebSockets and the rest of Next.js content.
今回はAPIルートにGraphQLサーバーを構築し、Todoアプリを作っていきたいので、Subscription
の機能は使わない事にし、この設定はSKIPします。
4. DB・Prisma
- DBには
PostgreSQL
を採用しました
4-1. PostgreSQL
-
compose.ymlファイルの作成
$ touch compose.yml
compose.ymlversion: '3.9' services: db: image: postgres:15.1 ports: - 5432:5432 volumes: - postgres:/var/lib/postgresql/data environment: - POSTGRES_USER=user # 自分で変更してください - POSTGRES_PASSWORD=password # 自分で変更してください - POSTGRES_DB=graphql-todo # 自分で変更してください volumes: postgres:
docker compose up -d
4-2. Prisma設定
prismaとはNodejs, TypeScriptで使えるORM(ObjectRelationalMapping)です
-
install
pnpm add prisma @prisma/client
-
init
pnpm prisma init
.envに
DATABASE_URL
を記述します。.envDATABASE_URL="postgresql://user:password@localhost:5432/graphql-todo?schema=public"
urlは、compose.yml
で設定した変数を用いて、
postgresql://${POSTGRES_USER}
:${POSTGRES_PASSWORD}
@localhost:5432/${POSTGRES_DB}
schema=public
になります。
-
Todoテーブルの作成
prisma/schema.prisma// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } + model Todo { + id String @id @default(cuid()) + content String + done Boolean @default(false) + createdAt String + }
-
migrate
$ pnpm prisma migrate dev Environment variables loaded from .env Prisma schema loaded from prisma/schema.prisma Datasource "db": PostgreSQL database "graphql-todo", schema "public" at "localhost:5432" ? Enter a name for the new migration: › addTodoTable Applying migration `20230413102125_add_todo_table` The following migration(s) have been created and applied from new schema changes: migrations/ └─ 20230413102125_add_todo_table/ └─ migration.sql Your database is now in sync with your schema.
migrateが成功すると、
prisma/
にmigrations
ディレクトリが作成され、中に実行されたSQLが入ったmigrationファイルが作成されます。
RubyOnRailsのORMである、Active Record
に慣れている人には割とイメージしやすいファイル構成かもしれません。. ├── prisma │ ├── migrations │ │ ├── yyyyMMddhhmmss │ │ │ └─ migration.sql │ │ └─ migration_lock.toml | └─ prisma.schema
次回: GraphQL
- 中編
- GraphQL Schema
- GraphQL Context
- GraphQL Code Generator
- GraphQL Resolver
- GraphQLサーバー修正