2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Next.js/Hasura】GraphQL環境を10分で構築

Last updated at Posted at 2023-06-11

はじめに

 最近謎にGraphQLが人気を集めている。
 以前インターン先でHasuraを利用する機会があったため爆速でGraphQL環境を構築する。
 最終的にプロダクトにはNest.jsが採用されHasuraは使ってないが、一通り触った所感個人開発を行うのにこれほど便利なものはないだろう。

環境構築

Hasuraの取得

 早速Hasura公式からdocker-compose.ymlファイルをダウンロードする。下記コマンドはwgetでの例であり、curlにも対応している。

wget https://raw.githubusercontent.com/hasura/graphql-engine/stable/install-manifests/docker-compose/docker-compose.yaml

 ダウンロードされたファイルからHASURA_GRAPHQL_ADMIN_SECRETをコメントインし、任意の値に書き換える。この値がフロントエンドと通信する際のSecretTokenとなる。

docker-compose.yml
- ## HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
+ HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey

Next.js appの作成

 先程ダウンロードしたファイルにnext.jsのための情報を追記する。下記サービスをservices項目に追加する。nodeバージョンとportは任意の値に書き換える。サンプルではnodeバージョン18、portは3000となっている。

docker-compose.yml
web:
    image: node:18
    restart: always
    volumes:
      - .:/opt/web
    working_dir: /opt/web
    ports:
      - "3000:3000"
    tty: true

 サービスの追加ができたら下記コマンドでコンテナ郡を立ち上げる。

docker-compose up
# docker-compose up -d   //バックグラウンドでの実行

 コンテナが立ち上がったらwebコンテナに入りnext.js appを作成する。app作成時の設定はデフォルトでも問題ない。作成するサービスにあわせて随時変更することを推奨。

docker-compose exec web bash
npx create-next-app@latest

 next.js appの作成が終わったら、コンテナ内でプロジェクトファイルを移動する。docker-compose.ymlファイルが存在るディレクトリとプロジェクトディレクトリを同じ階層にするために行う。プロジェクトディレクトリを移行しない場合はdocker-compose.ymlファイル内webサービスのvolumesを書き換える必要がある。

mv $app_name .
rm -r $app_name

 現在作成されたファイルはすべてroot権限となっているため、プロジェクトディレクトリ以下のファイル権限を変更する。プロジェクトディレクトリがある階層に移動し、下記コマンドで権限を変更する。権限を変更しないとファイル変更時に毎回パスワードを聞かれ面倒。

sudo chmod 755 -R app_name
sudo chown $USER:$USER -R app_name

 最後に、docker-compose.ymlにコマンドを設定し、コンテナ起動時にnext.js serverが立ち上がるよう変更を加える。先程追加したwebサービスを一部書き換える。

docker-compose.yml
- tty: true
+ command: npm run start

Next.jsからHasuraに接続

 Appolo Clientを用いてNext.jsからHasuraに接続する。webコンテナ内から下記コマンドを用いてgraphqlとapollo clientをインストールする。

npm i @apollo/client graphql

インストールが終わったら、Hasuraに接続するための情報を.envファイルにまとめる。NEXT_PUBLIC_HASURA_ADMIN_SECRETの値はdocker-compose.ymlファイルで記載した値を記入する。

.env
NEXT_PUBLIC_GRAPHQL_ENDPOINT = http://localhost:8080/v1/graphql
NEXT_PUBLIC_HASURA_ADMIN_SECRET = myadminsecretkey

 実際にHasuraに接続するため、apollo clientのproviderを設定する。headersにx-hasura-admin-secretを設定する。

_app.tsx
import "@/styles/globals.css";
import {
  ApolloClient,
  ApolloProvider,
  InMemoryCache,
  createHttpLink,
} from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
import type { AppProps } from "next/app";

const httpLink = createHttpLink({
  uri: process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT,
});

const authLink = setContext((_, { headers }) => {
  return {
    headers: {
      ...headers,
      "x-hasura-admin-secret": process.env.NEXT_PUBLIC_HASURA_ADMIN_SECRET,
    },
  };
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
});

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

おまけ

ChakraUIの設定

 webコンテナ内からChakraUIをインストールする。

npm i @chakra-ui/react @chakra-ui/next-js @emotion/react @emotion/styled framer-motion

 ChakraUIを利用するため、_app.tsxにProviderの設定を行う。

_app.tsx
+ import { ChakraProvider } from "@chakra-ui/react";

export default function App({ Component, pageProps }: AppProps) {
  return (
+     <ChakraProvider>
        <ApolloProvider client={client}>
          <Component {...pageProps} />
        </ApolloProvider>
+     </ChakraProvider>
  );
}

おわりに

 以上でGraphQL環境の構築が完了する。実際にhttp://localhost:3000 にアクセスするとnext.jsに、http://localhost:8080 にアクセスするとHasuraにアクセスが可能。
 では、良いエンジニアライフを。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?