22
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.js + GrapqhQLでTodoアプリを構築する(前編)

Last updated at Posted at 2023-04-15

はじめに

最近GraphQLについて学びまして、
Next.js + GraphQL + GraphQL CodeGenerator + Prismaの構成でTodoアプリを構築したので
解説をしつつ、その記録をここに残します。

スクリーンショット 2023-04-15 20.58.42.png

環境

  • Macbook Air
  • node
    • v18.13.0
  • pnpm
    • 7.27.0

目次

  • 前編 👈 今ここ
    1. Next Create App
    2. GraphQLサーバー構築
    3. Subscription
    4. DB・Prisma
  • 中編
    1. GraphQL Schema
    2. GraphQL Context
    3. GraphQL Code Generator
    4. GraphQL Resolver
    5. GraphQLサーバー修正
  • 後編
    1. フロント側準備
    2. フロント側実装

前編

前編は準備フェーズです。

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でサーバーが起動します。

    スクリーンショット 2023-04-15 12.43.47.png

2. GraphQLサーバー構築

  • install

    $ pnpm add graphql graphql-yoga
    
  • GraphQL Server on api/graphql.ts

    src/pages/api/graphql.ts
    import { 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'
    })
    

    localhost:3000/api/graphql

    image.png

    YogaGraphQLサーバーが立ち上がっています。
    試しにQueryを叩いてみます。

    image.png

    ちゃんと叩けました👍

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.yml
    version: '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を記述します。

    .env
    DATABASE_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
    
  • prisma studioの起動

    prismaには入っているデータの検索、操作を簡単に行えるprisma studioというものが標準で用意されています。

    pnpm prisma studio
    

    スクリーンショット 2023-04-15 20.28.22.png

次回: GraphQL

  • 中編
    1. GraphQL Schema
    2. GraphQL Context
    3. GraphQL Code Generator
    4. GraphQL Resolver
    5. GraphQLサーバー修正
22
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?