はじめに
最近謎に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となる。
- ## HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
+ HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
Next.js appの作成
先程ダウンロードしたファイルにnext.jsのための情報を追記する。下記サービスをservices項目に追加する。nodeバージョンとportは任意の値に書き換える。サンプルではnodeバージョン18
、portは3000
となっている。
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サービスを一部書き換える。
- 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ファイルで記載した値を記入する。
NEXT_PUBLIC_GRAPHQL_ENDPOINT = http://localhost:8080/v1/graphql
NEXT_PUBLIC_HASURA_ADMIN_SECRET = myadminsecretkey
実際にHasuraに接続するため、apollo clientのproviderを設定する。headersにx-hasura-admin-secret
を設定する。
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の設定を行う。
+ 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にアクセスが可能。
では、良いエンジニアライフを。