HonoでGraphQLサーバーを構築する
はじめに
こんにちは、soso です!
最近 Hono×GraphQL で試しにサーバーを構築してたので、その内容をまとめてみました。今回は Cloudflare Workers にデプロイする前提で書いています。Workers で GraphQL サーバーを構築する場合、Hono を使わず graphql-yoga
を使うなどの選択肢もあります。今回は Hono でも GraphQL サーバーをどれぐらい快適に構築できるかの検証も含めて、Hono を使ってやっていきます。
GraphQL 自体は無駄に複雑だし REST&OpenAPI で十分でしょ。的な意見も最近はよく聞きますが、個人的にはまだまだ第一選択肢になると思ってます。統計取ったわけじゃないので完全に個人の感覚ですが、プロジェクトの機能追加や仕様変更に対して柔軟なクエリによって Schema 変更無しで対応、みたいなケースが多いです。REST なら新しいエンドポイント追加するか、クライアント側で API を複数回叩いてパフォーマンスを悪化させるかみたいなことになりがち。もちろん GraphQL は GraphQL で N+1 問題やらキャッシュやら問題はありますが、柔軟なクエリによって追加対応無しにして本来プロダクトでやりたかったことに集中できるのは強いメリットだと思っています。
Hono
言わずと知れた軽量なフレームワークです。紹介記事は世にたくさんあるので、ここでは割愛します。
まずは Hono のセットアップをして GraphQL サーバーを構築する下地を作ります。
npm create hono@latest
# or
yarn create hono
import { Hono } from "hono";
const app = new Hono();
app.get("/", (c) => {
return c.text("Hello Hono!");
});
export default app;
ここまではいつも通りの Hono のセットアップです。
@hono/graphql-server
Hono には GraphQL サーバーを簡単に構築するための @hono/graphql-server
ミドルウェアが公式で用意されています。
npm i @hono/graphql-server graphql
# or
yarn add @hono/graphql-server graphql
インストール後はミドルウェアを /graphql
のエンドポイントに設定するだけです。簡単ですね。
import { graphqlServer } from "@hono/graphql-server";
import { buildSchema } from "graphql";
import { Hono } from "hono";
import { schema as originSchema } from "./graphql/generated/schema";
const app = new Hono();
const schema = buildSchema(originSchema);
const rootResolver = (c) => {
return {
hello: () => "Hello Hono GraphQL!",
};
};
app.use(
"/graphql",
graphqlServer({
schema,
rootResolver,
graphiql: true,
})
);
export default app;
graphiql: true
にしておくと、ブラウザで対象エンドポイント(今回であれば http://localhost:8787/graphql
)にアクセスした時に GraphiQL の UI が表示されるようになります。デバッグに便利なので開発環境では有効にしておきましょう。
確認
サーバーを立ち上げてリクエストすると想定通りにデータが返ってくることを確認できます。
curl -X POST \
-H "Content-Type: application/json" \
-d '{"query": "query { hello }"}' \
"http://localhost:8787/graphql"
{"data":{"hello":"Hello Hono GraphQL!"}}
ハマったところ
ここで 1 点注意点があります。Hono というよりは Cloudflare Workers の話なのですが、Workers では fs
が使えません。つまり GraphQL サーバーのスキーマをファイル読込できないのでよくやる以下のようなコードや graphql
ライブラリのファイル読み込み関数でエラーになります。
const schema = loadSchemaSync("./schema.graphql");
これを回避するために、スキーマファイルを文字列に変換するスクリプトを用意して、ビルド時に文字列化したスキーマを渡すようにしました。
最近の話ですが、Workers の更新で nodejs_compat_v2
で fs
を含めた多くの Node.js API に対するポリフィルが追加されたので、このあたりのライブラリが動かない問題は解消されていきそうではあります。(とはいえバンドルサイズが増えてしまうのは少し気になるところ)
まとめ
Hono で GraphQL サーバーを構築してみましたが、非常に簡単でした。有名どころの機能であればミドルウェアで提供されていることが多いので、簡単に導入できるのが Hono のいいところですね。
参考
Discussion