ReactのフレームワークNext.jsのAPI Routesを利用してGraphQLサーバを構築してVercelにデプロイするまでの流れを説明しています。

GraphQLサーバにはApollo Server、 データベースの接続にはPrisma、データベースにはSupabaseのPostgreSQLを利用しています。複雑な設定やアプリケーションの構築は行なっていないのでデプロイ後のブラウザ上に表示されるのはSupabaseのPostgreSQLに保存されたデータをPrisma経由で取得してNext.jsのフロントエンドのApollo ClientからApollo Serverのエンドポイント(/api/graphql)にアクセスを行って取得したデータです。

ブラウザ上に表示
ブラウザ上に表示

利用した技術/サービスについては本ブログでも記事を公開しているので参考にしてみてください。

GitHubのアカウントを利用してSupbaase, Vercelのサインアップを行うのでGitHubアカウントの取得は必須です。

プロジェクトの作成

Next.jsのプロジェクトの作成を行います。npx create-next-appコマンドに–tsをつけてTypeScriptもインストールしています。プロジェクト名にnext_js_projectとつけていますが任意の名前を設定してください。


 % npx create-next-app --ts next_js_project
 

コマンドを実行するとnext_js_projectフォルダが作成されます。

GraphQLの動作確認

GraphQLのインストール

GraphQLサーバのApollo Serverを動かすためにNode.jsのWeb Application Frameworkのmicroを利用します。microは軽量でシンプルなWeb Application Frameworkです。microをイメージしにくい場合はExpressと同様のものだと考えてください。

micro用のApollo Serverのapollo-server-microもインストールを行います。


 % npx install apollo-server-micro micro graphql

GraphQLサーバの設定

Next.jsでバックエンドのAPIを設定することができるAPI Routesはデフォルトから特別な設定なしで利用することができます。API Routesのエンドポイントのファイルは/pages/apiの下に保存します。デフォルトではhello.tsxファイルが存在しブラウザから/api/helloにアクセスを行うとnameプロパティにJohe Doeの値を持つオブジェクトが戻されます。

API Routesを利用してApollo Serverを起動するため、micor, apollo-server-microのインストールが完了したらGraphQLサーバ(Apollo Server)の動作を確認するために/pages/apiフォルダにgraphql.tsファイルを作成します。

graphql.tsファイルにはApollo Sereverの起動に関するコードだけではなくGraphQLのスキーマ(typeDefs)やリゾルバ(Resolvers)の設定も記述します。機能/役割毎にファイルを分けることができますが今回は複雑は設定はないのでgraphql.tsファイルに設定を行っていきます。

GraphQLではスキーマの設定を行う必要があります。スキーマのQueryタイプにhelloを定義します。Queryタイプでは戻り値のタイプを設定します。helloを実行した場合はStringである文字列が戻されることになります。Queryタイプは定義のみで実際の処理は記述しないので実際の処理をはリゾルバに記述します。helloのリゾルバの設定により”Hello World”が戻されます。 Queryタイプのhelloの戻り値のタイプであるString(文字列)と一致する必要があります。


//略
const typeDefs = gql`
  type Query {
    hello: String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello World',
  },
};
//略

Apolloサーバのインスタンスを作成するために引数にはスキーマの定義とリゾルバの設定を行い起動しています。パスに設定した/api/graphqlがGraphQL唯一のエンドポイントです。REST APIとは異なりGraphQLではクライアントから1つのエンドポイントに対してアクセスが行われます。


import { ApolloServer, gql } from 'apollo-server-micro';
import type { NextApiRequest, NextApiResponse } from 'next';

const typeDefs = gql`
  type Query {
    hello: String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello World',
  },
};

const apolloServer = new ApolloServer({
  typeDefs,
  resolvers,
});

const startServer = apolloServer.start();

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  
  await startServer;
  await apolloServer.createHandler({
    path: '/api/graphql',
  })(req, res);
}

export const config = {
  api: {
    bodyParser: false,
  },
};

handler関数の中でsetHeaderの設定を行いますがこれはCORS(Cross Origin Resource Sharing)に関する設定でhttps://studio.apollographql.comからのアクセスの許可を行なっています。同じOriginのローカルとhttps://studio.apollographql.com以外からはアクセスを行うことができません。


//略
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  res.setHeader(
    'Access-Control-Allow-Origin',
    'https://studio.apollographql.com'
  );
  res.setHeader(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept'
  );
  if (req.method === 'OPTIONS') {
    res.end();
    return false;
  }

  await startServer;
  await apolloServer.createHandler({
    path: '/api/graphql',
  })(req, res);
}
//略
CORSの設定にはmicro-corsを利用することができます。

Apollo Studio Explorerからの接続

graphsql.tsファイルの設定が完了したらGraphQLサーバの設定が問題なく行われているか確認するためにnpm run devコマンドでNext.jsの開発サーバを起動します。


 % npm run dev

> next_js_project@0.1.0 dev
> next dev

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait  - compiling...
event - compiled client and server successfully in 499 ms (125 modules)

起動後はNext.jsのAPI Routesのエンドポイントであるhttp://localhost:3000/api/graphqlにアクセスします。

/api/graphsqlアクセス後に表示される画面
/api/graphsqlアクセス後に表示される画面

“Query your server”ボタンをクリックすると”Apollo Server Studio”が起動します。GUIを利用してGraphQLサーバのスキーマで設定(graphql.ts)したクエリーを実行することができます。

DecumentationのFiledsの下にあるhelloがチェックされていることとOperationにhelloが記述されていることを確認して”ExampleQuery”ボタンをクリックすると右側のResponseに”Hello World”が表示されます。

画面上でhelloを実行
画面上でhelloを実行
このようにApollo Studio Explorerを利用することで GraphQLの動作確認を行うことができます。ブラウザのURLを見るとstudio.apollograhpql.comであることがわかります。graphql.tsのCORSの設定で’Access-Control-Allow-Origin’で設定した’https://studio.apollographql.com’と一致することがわかります。CORSの設定はApollo Studio Exploreを利用することも目的に設定していることがわかります。

CORSの設定を行なっていない場合にはブラウザのデベロッパーツールのコンソール画面にCORSに関するエラーメッセージが表示されます。

CORSのエラー
CORSのエラー

CORSが正しく設定されている場合にはAPOLLOのロケットだけ表示されエラーメッセージは表示されません。

CORSが正しく設定されている場合
CORSが正しく設定されている場合

GraphQLの動作確認はcurlコマンドでも行うことができます。/api/graphqlにアクセスした際に表示されていたcurlコマンドを参考に実行します。REST APIの場合はデータを取得する場合にはGETリクエストを送信しますがGraphQLではエンドポイントに対してどのようなクエリーを実行するか情報を送信する必要があるためPOSTリクエストを実行することになります。


 % curl --request POST \
  --header 'content-type: application/json' \
  --url http://localhost:3000/api/graphql \
  --data '{"query":"query { hello }"}'
  
{"data":{"hello":"Hello World"}}

スキーマの追加

スキーマのQueryタイプにhelloのみ追加し動作確認を行いましたがスキーマにオブジェクトタイプのUserを追加します。Userタイプを追加後にQueryタイプにusersを追加します。usersの戻り値には配列のUserタイプを指定しています。usersのクエリーを実行するとUserタイプのデータ構造を持つ配列を戻すことを定義しています。


const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
  }

  type Query {
    hello: String
    users: [User]
  }
`;

Queryタイプに追加したusersクエリーの実際の処理をリゾルバに記述します。usersの関数で戻されるusersはファイルの先頭で定義しておきます。usersの配列の各要素はスキーマで定義してUserタイプと同じです。


//略
const users = [
  { id: '1', name: 'John Doe', email: 'john@test.com' },
  { id: '2', name: 'Jane Doe', email: 'jane@example.com' },
];
//略
const resolvers = {
  Query: {
    hello: () => 'Hello World',
    users: () => users,
  },
};

Apollo Studio Explorerを利用して追加したusersクエリーが実行できるか確認します。設定した通りusersが戻されることが確認できればここまでの設定は正常に問題なく行われています。

Apollo Studio Explorerによるusersクエリーの実行
Apollo Studio Explorerによるusersクエリーの実行

戻されるusersの値を手動で設定し動作することが確認できました。次はデータベースに保存されたusersを取得できるようにPrismaやSupabaseの設定を行っていきます。

PrismaとDBの設定

Prismaのインストール

PrismaはNode.js/TypeScript環境で利用できるオープンソースのORM(Object Relational Mapping)です。Prismaを利用することでデータベースの管理、操作を効率的に行うことができ、データベースの操作にはSQLではなくメソッドを利用して行います。


 % npm install prisma --save-dev

インストールが完了するとprismaコマンドを利用することができます。


 % npx prisma

◭  Prisma is a modern DB toolkit to query, migrate and model your database (https://prisma.io)

Usage

  $ prisma [command]

Commands

            init   Set up Prisma for your app
        generate   Generate artifacts (e.g. Prisma Client)
              db   Manage your database schema and lifecycle
         migrate   Migrate your database
          studio   Browse your data with Prisma Studio
          format   Format your schema

Flags

     --preview-feature   Run Preview Prisma commands

Examples

  Set up a new Prisma project
  $ prisma init

  Generate artifacts (e.g. Prisma Client)
  $ prisma generate

  Browse your data
  $ prisma studio

  Create migrations from your Prisma schema, apply them to the database, generate artifacts (e.g. Prisma Client)
  $ prisma migrate dev
  
  Pull the schema from an existing database, updating the Prisma schema
  $ prisma db pull

  Push the Prisma schema state to the database
  $ prisma db push

Prismaの初期設定を行うためにprisma initコマンドを実行します。実行するとプロジェクトフォルダの直下にprismaフォルダが作成され、prismaの設定ファイルであるschema.prismaファイルが作成されます。


  % npx prisma init

✔ Your Prisma schema was created at prisma/schema.prisma
  You can now open it in your favorite editor.

warn You already have a .gitignore. Don't forget to exclude .env to not commit any secret.

Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb (Preview).
3. Run prisma db pull to turn your database schema into a Prisma schema.
4. Run prisma generate to generate the Prisma Client. You can then start querying your database.

More information in our documentation:
https://pris.ly/d/getting-started

schema.prismaファイル

Prismaの設定を行うschema.prismaのファイルの中身を確認します。デフォルトではgenaratorとdatasourceの2つが設定されています。shema.prismaファイルではその他にmodelを設定する必要があります。modelを設定することでデータベースに作成するテーブルの構成が決まります。

genaratosの設定

generatorはschema.prismaファイルで設定された内容を元にPrisma Clientを作成するために利用します。接続するデータベースや設定するmodelの内容によって作成されるPrisma Clientの内容が変わります。Prisma Clientの作成方法については後ほど説明を行います。

datasourceの設定

datasourceではPrismaが接続するデータベースの設定を行なっています。providerには接続するデータベース、urlにはデータベースに接続するためのURLを設定します。env関数で囲まれているDATABASE_URLは環境変数で.envファイルに記述されています。


generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

.envファイルのDATABASE_URLにはproviderに設定されているデータベースPostgreSQLへの接続情報が設定されていますが各自の環境にあった値に変更する必要があります。


DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

SupabaseのPostgreSQLへの接続

SupabaseはPostgreSQLデータベースを利用することができるオープンソースのクラウドサービスです。

Supabaseを利用するためにはサインインを行う必要があります。サインインを行う場合はGitHubのアカウントを利用して行います。

Supabaseのサイトにアクセスして画面の”Start your project”からGithubのアカウントを利用してサインアップを行います。

Supabaseのトップページ
Supabaseのトップページ

GitHubアカウントによるSupabaseの認証画面が表示されるのでGitHubアカウントでサインインすることに問題がなければ”Authorize supabase”ボタンをクリックしてください。

GitHubアカウントとの連携
GitHubアカウントとの連携

GitHubのアカウントでのサインインが完了したら管理画面が表示されます。画面の中央には”New Project”ボタンがあります。

GitHubのアカウントでサインインすることでできサインイン後にプロジェクトを作成します。

プロジェクトの作成
プロジェクトの作成

プロジェクトの作成ではプロジェクトの名前とデータベースのパスワード、Region(場所)の設定を行います。データベースのパスワードはPrismaから接続する際に必要になります。プロジェクトは任意の名前をつけてください。Regionには東京があるので東京を選択します。

プロジェクトの作成
プロジェクトの作成

データベースへの接続はschema.prismaファイルのdatasourceで行います。接続情報はSupabaseの管理画面から確認することができます。

プロジェクトが完了するまで少し時間がかかります。プロジェクトが完了するまでデータベースの接続情報などは確認できません。

左側のメニューの一番下にあるSettingを選択して、Project settingの下に表示されるDatabaseを選択します。画面を下までスクロールするとConnection Stringの項目があるので”Node.js”のタブを開いてそこに表示されている接続用の文字列をコピーしてください。

Node.jsからの接続情報
Node.jsからの接続情報

コピーしたらプロジェクトフォルダにある.envファイルを開いてDATABASE_URLにペーストしてください。[YOUR_PASSWORD]にはSupabaseのプロジェクトの作成時に入力したパスワードを入れてください。


DATABASE_URL="User Id=postgres;Password=[YOUR-PASSWORD];Server=db.ewziugcyjy1qdxaHxzsme.supabase.co;Port=5432;Database=postgres"

データベースに接続するための設定は完了したのでデータベースに作成するテーブルの構成を決めるため次はPrismのschema.prismaファイルでmodelの設定を行います。

Userモデルの追加

schema.prismaファイルでmodelの設定を行います。GraphQLのgraphql.tsでも定義したUserモデルを元に設定を行います。schema.prismaのmodel Userではフィールドを設定していきます。各フィールドは名前と型とオプションを設定することができます。


generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id      Int      @id @default(autoincrement())
  email   String   @unique
  name    String?
}

UserモデルとUserテーブルは1対1に対応するためUserテーブルはid, email, nameの列を持つことになります。idはInt型でemailとnameは文字列なのでString型を設定しています。Stringの横に?がついているのはnameはオプションでnullでもいいことを表しています。

@idはのPostgreSQLのようなリレーショナルデータベースではプライマリキーになることを表しています。@defaultはデフォルト値を設定することができ、autoincrement()を引数に設定しているのでデータを追加する度にidの値が自動で加算されます。@uniqueはemail列で一意の値のみ登録することができることを意味します。

マイグレーションの実行

schema.prismaファイルによるデータベースの接続とmodelの設定が完了したのでPrisma Clientの作成とデータベースへのUserテーブルの作成を行うためにPrismaのコマンドを利用します。マイグレーションコマンドを実行する時にマイグレーションに任意の名前をつけることができます。名前をつけるのはマイグレーションを管理する際に楽にするためです。


 % npx prisma migrate dev
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "db.ewziugcyjy1qdxaHxzsme.supabase.co:5432"

✔ Enter a name for the new migration: … init
Applying migration `20220522012256_init`

The following migration(s) have been created and applied from new schema changes:

migrations/
  └─ 20220522012256_init/
    └─ migration.sql

Your database is now in sync with your schema.

✔ Generated Prisma Client (3.14.0 | library) to ./node_modules/@prisma/client in 468ms

コマンドを実行するとprismaフォルダの下にmigrationsフォルダが作成され実行時刻とマイグレーション時に入力した名前のフォルダが作成されます。その下にはmigration.sqlファイルが作成されテーブルを作成するためのCREATE TABLE文が記述されています。CREATE TABLE文は接続するデータベースによって内容が変わります。データベースによってデータタイプや各種設定に違いがあるためです。


-- CreateTable
CREATE TABLE "User" (
    "id" SERIAL NOT NULL,
    "email" TEXT NOT NULL,
    "name" TEXT,

    CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

マイグレーションコマンドによってテーブルが作成できるかどうか確認するためにSupabasaの管理画面を確認します。左側のメニューのTable EditorをクリックするとAll tablesに作成されたテーブルの情報が確認できます。Userテーブルの他に_prisma_migrationsテーブルも確認することができます。

Supabaseからのテーブル作成の確認
Supabaseからのテーブル作成の確認

_prisma_migrationsテーブルにはマイグレーションの情報が保存されていることが確認できます。

_prisma_migrationsテーブルの確認
_prisma_migrationsテーブルの確認

Prisma Studioの利用

PrismaにはGUIでデータベース管理を行うためのPrisma Studioがあります。Prisma Studioを起動するために”npx prisma studio”コマンドを実行します。


 % npx prisma studio
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Prisma Studio is up on http://localhost:5555
 

コマンドを実行するとブラウザが自動で起動しhttp://localhost:5555にアクセスが行われます。画面には設定したモデルが表示され選択することができます。現在はUserモデルしかないためUserのみ表示されています。Supabaseの管理画面のテーブルで確認した_prisma_migrationsにはPrisma Studioからアクセスすることはできません。

Prisma Studioの起動直後の画面
Prisma Studioの起動直後の画面

Userをクリックするとデータは入っていませんがUserテーブルの列名を確認することができます。

Userテーブルの列名の確認
Userテーブルの列名の確認

Prisma Studioからはデータの登録を行うことができるので”Add record”ボタンを押して2名分のデータを登録します。2名登録すると以下のように表示されます。

Userテーブルへのデータ追加
Userテーブルへのデータ登録

Apollo ServerからDBへの接続

Apollo Serverのインスタンスを作成する際に引数のオブジェクトにtypeDefs, resolversを設定しましたがそれ以外にもオプションを利用することができます。データベースに接続する際は、オプションの1つであるcontextを利用することができます。

graphql.tsファイルの先頭でprisma/clientからimportしたPrismaClientをインスタンス化します。インスタンス化したPrismClientをApollo Serverのインスタンス化する際にcontextを通して設定します。


import { ApolloServer, gql } from 'apollo-server-micro';
import type { NextApiRequest, NextApiResponse } from 'next';

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

//略

const apolloServer = new ApolloServer({
  typeDefs,
  resolvers,
  context: {
    prisma,
  },
});

//略

実際のクエリーの処理はリゾルバで行うためリゾルバでcontextを使って設定されたprismaを利用できるように設定を行う必要があります。

リゾルバの関数にはこれまで引数を設定していませんでしたがparent, args, context, infoの4つ引数を受け受け取ることができます。この3つ目のcontextを利用することでcontextにアクセスすることができcontext.prismaでprismaにアクセスすることが可能になります。


interface Context {
  prisma: PrismaClient;
}

const resolvers = {
  Query: {
    hello: () => 'Hello World',
    users: async (parent: undefined, args: {}, context: Context) => {
      return await context.prisma.user.findMany();
    },
  },
};

Prismaについて説明した通り、データベースへの操作はSQLではなくメソッドを利用して行います。context.prisma.user.findManyメソッドでPrismaで接続したデータベースのuserテーブルからすべてのデータ(レコード)を取得しています。

データベースのuserテーブルからデータを取得するのでgraphql.tsで設定したusers変数は削除してください。

Apollo ServerからPrismaを介してSupabaseのPostgreSQLのuserテーブルにアクセスする設定が完了したのでApollo Server Explorerを利用してusersクエリーを実行します。

実行するとSupabseのPostgreSQLデータベースのUserテーブルに保存されたユーザ情報をApollo Server, Prismaを介して取得することができました。

Apollo Studio Explorerからのusersクエリー
Apollo Studio Explorerからのusersクエリー

フロントエンド側の設定

API Routesを利用したバックエンドのGraphQLサーバ側での設定が完了したのでフロントエンド側での設定を行います。フロントエンド側ではApollo Clientのインストールを行います。GraphQLサーバ側で設定したusersクエリーを利用するためApollo Clientを通してエンドポイントである/api/graphqlに対してPOSTリクエストを実行します。

Apollo Clientのインストール


 % npm install @apollo/client

インストールしたApollo Clientを通してユーザ情報が取得できるか確認します。

pagesフォルダにあるindex.tsxファイルでApollo Clinetの初期化を行います。その際にuriとcacheの引数を設定しています。uriはGraphQLのエンドポイントであるhttp://localhost:3000/api/graphqlを設定し、取得したデータをキャッシュするためのcacheを設定しています。cacheにはInMemoryCacheを利用しています。


import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:3000/api/graphql',
  cache: new InMemoryCache(),
});

クエリーを記述します。クエリーはimportしたgqlの利用して記述しますがその際にバックティック(` `)を利用します。取得したデータはブラウザのデベロッパーツールのコンソールに表示されるように設定しています。


client
  .query({
    query: gql`
      query GetUsers {
        users {
          id
          name
          email
        }
      }
    `,
  })
  .then((result) => console.log(result));

Apollo Clientによる処理を追加した後のindex.tsxファイルの中身は下記のようになります。


import type { NextPage } from 'next';
import Head from 'next/head';
import styles from '../styles/Home.module.css';

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:3000/api/graphql',
  cache: new InMemoryCache(),
});

client
  .query({
    query: gql`
      query GetUsers {
        users {
          id
          name
          email
        }
      }
    `,
  })
  .then((result) => console.log(result));

const Home: NextPage = () => {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1>ユーザ情報</h1>
      </main>
    </div>
  );
};

export default Home;

npm run devを実行した状態でhttp://localhost:3000にアクセスするとコンソールに取得したユーザ情報が確認できます。フロントエンド側からもSupabaseのPostgreSQLに保存されたユーザ情報を取得できるようになりました。

Apollo Clientによるデータ取得の確認
Apollo Clientによるデータ取得の確認

index.tsxファイルでGraphQLのクエリーを実行できるようになりましたがすべてのコンポーネントでApollo Clientが利用できるように_app.tsxファイルでApollo Clientの設定を行います。

_app.tsxファイルに先ほど設定したApollo Clientの設定を行い、Apollo ProviderタグでComponentタグを包みます。


import '../styles/globals.css';
import type { AppProps } from 'next/app';

import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';

const client = new ApolloClient({
  uri: '/api/graphql',
  cache: new InMemoryCache(),
});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  );
}

export default MyApp;

Apollo ClientはuseQuery Hookも提供しており、useQuery Hookを利用することでデータの取得の状態やエラー情報を取得することができます。

index.tsxではuseQuery Hookを利用してGraphQLサーバからデータを取得してブラウザ上に表示するコードを記述します。


import type { NextPage } from 'next';
import Head from 'next/head';
import styles from '../styles/Home.module.css';

import { gql, useQuery } from '@apollo/client';

const GET_USERS = gql`
  query GetUsers {
    users {
      id
      name
      email
    }
  }
`;

const Home: NextPage = () => {
  const { data, loading, error } = useQuery(GET_USERS);

  if (loading) return <p>ローディング中です</p>;
  if (error) return <p>エラーが発生しています</p>;

  const { users } = data;

  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1>ユーザ情報</h1>
        {users.map((user: { id: number; name: string; email: string }) => (
          <div key={user.id}>Name: {user.name}</div>
        ))}
      </main>
    </div>
  );
};

export default Home;

useQueryの引数にはクエリーを記述します。useQueyの戻り値からdata, loading, errorを取得します。loading, errorの値と分岐を利用してブラウザ上に表示する内容を変えています。dataの中に入っているusersを取り出してmap関数で展開してユーザ名をブラウザ上に表示しています。

ブラウザからlocalhost:3000にアクセスした瞬間、画面には”ローディング中です”が表示されます。データの取得が完了したら下記のようにユーザ名が表示されます。

ブラウザ上に表示されたユーザ名
ブラウザ上に表示されたユーザ名

もし取得に失敗した場合にはブラウザ上には”エラーが発生しています”が表示されます。

ここまでの設定でブラウザ上にユーザ名が表示されたので次はVercelへのデプロイ方法を確認します。

デプロイ

GitHubに経由してVercelでデプロイを行うためSupabaseと同様にGitHubのカウントを利用します。

Apollo ClientのURIの変更

現在の設定では_app.tsxにおけるApolloClientのuriの設定がhttp://localhost:3000/api/graphqlになっているので/api/graphqlに変更します。変更を忘れた場合はデプロイ後にデータ取得に失敗しデベロッパーツールのコンソールにCORS(Cross Origin Resource Share)のエラーが表示されます。


const client = new ApolloClient({
  uri: '/api/graphql',
  cache: new InMemoryCache(),
});

GitHubでのリポジトリの作成

GitHubにログインを行い、新規のリポジトリの作成を行うため”New”ボタンをクリックします。

新規リポジトリの作成
新規リポジトリの作成

新規のリポジトリ作成画面が表示されるのでRepository nameの設定を行います。リポジトリの公開設定は非公開の”Private”に設定しています。設定が完了したら”Create repository”ボタンをクリックします。

リポジトリの新規作成画面
リポジトリの新規作成画面

リポジトリの作成が完了するとローカルのPCからGitHubのリポジトリにアップロードする手順が表示されます。

コマンドラインでのローカルの設定方法
コマンドラインでのローカルの設定方法

GitHubへのアップロード

プロジェクトの作成が完了したら作成したGitHubリポジトリにプロジェクトファイルのアップロードを行います。

Prisma用の環境変数DATABASE_URLを保存した.envファイルをGitHubのリポジトリにアップロードしないように.gitignoreファイルに.envを追加しておきます。

git initコマンドでローカルにリポジトリの作成を行います。


 % git init
Reinitialized existing Git repository in /Users/mac/Desktop/next_js_project/.git/

ローカルリポジトリにすべてのファイルを加えるためgit addコマンドを実行します。


 % git add .

git commitコマンドを実行してgit addで追加したファイルをcommitします。


 % git commit -m "first commit"
[main e99d79a] first commit
 10 files changed, 9265 insertions(+), 1784 deletions(-)
 create mode 100644 package-lock.json
 rewrite pages/_app.tsx (69%)
 create mode 100644 pages/api/graphql.ts
 rewrite pages/index.tsx (85%)
 create mode 100644 prisma/migrations/20220522012256_init/migration.sql
 create mode 100644 prisma/migrations/migration_lock.toml
 create mode 100644 prisma/schema.prisma
 rewrite yarn.lock (92%)

リモートのリポジトリの設定を行います。[gitユーザ名]/first-next-vercel.gitは各環境に合わせて変更を行ってください。GitHubでリポジトリを作成した際に表示されているURLを利用します。


 % git remote add origin https://github.com/[githubユーザ名]/first-next-vercel.git

最後にgit pushコマンドでGitHubのリポジトリにプッシュ(アップロード)します。


% git push -u origin main 
Enumerating objects: 38, done.
Counting objects: 100% (38/38), done.
Delta compression using up to 4 threads
Compressing objects: 100% (35/35), done.
Writing objects: 100% (38/38), 126.04 KiB | 6.63 MiB/s, done.
Total 38 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (4/4), done.
To https://github.com/[githubユーザ名]/next-js-grapql.git
 * [new branch]      main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.  

pushが完了するとGitHubのリポジトリにファイルが追加されるので確認してください。

Vercelの設定

Vercelを利用するためには事前にVercelのサインアップを行っておく必要があります。

Vercelへのサインアップが完了したら下記の画面が表示されます。

Vercelへのサインアップ完了
Vercelへのサインアップ完了

Vercelにインポートするリポジトリの選択を行うためImport Git Repositoryの下にある虫眼鏡をクリックしてください。クリックしたら”Add GitHub Org or Account”を選択してください。

Gtリポジトリの選択
Gtリポジトリの選択

インポートするリポジトリの選択を行います。ここではGitHubでNext.jsのために作成したnext-js-graphqlのみ選択しています。選択したら”Install”ボタンをクリックしてください。

リポジトリのVercelへのインストール画面
リポジトリのVercelへのインストール画面

下記の画面が表示されるので”Import”ボタンをクリックします。

Import画面
Import画面

Importボタンをクリックするとプロジェクトの設定画面が表示されるのでPROJECT NAMEなどを設定することができます。デフォルトではGitHubのリポジトリ名が設定されています。環境変数のDATABASE_URLを設定する必要があるので.envの内容を元に”Environment Variables”を開いて設定を行なってください。

プロジェクトの設定
プロジェクトの設定

設定が完了したら一番下にある”Deploy”をクリックします。

デプロイの処理が開始されます。ビルド処理が行われるため1分〜数分時間がかかります。

デプロイの進行中
デプロイの進行中

デプロイが完了すると完了画面が表示されvercel.appのドメイン上でユーザ情報が表示されればデプロイの処理は成功しています。

ブラウザ上に表示
ブラウザ上に表示

デプロイが完了したのでNext.js, GraphQL(Apollo Server), Prisma, Supabase, Apollo Clientを組み合わせた環境でもここまでの設定であれば問題なく動作することが確認できました。