Gemcook Tech Blog
🚀

HonoでGraphQLサーバーを構築する

2024/09/17に公開

はじめに

こんにちは、soso です!
最近 Hono×GraphQL で試しにサーバーを構築してたので、その内容をまとめてみました。今回は Cloudflare Workers にデプロイする前提で書いています。Workers で GraphQL サーバーを構築する場合、Hono を使わず graphql-yoga を使うなどの選択肢もあります。今回は Hono でも GraphQL サーバーをどれぐらい快適に構築できるかの検証も含めて、Hono を使ってやっていきます。

GraphQL 自体は無駄に複雑だし REST&OpenAPI で十分でしょ。的な意見も最近はよく聞きますが、個人的にはまだまだ第一選択肢になると思ってます。統計取ったわけじゃないので完全に個人の感覚ですが、プロジェクトの機能追加や仕様変更に対して柔軟なクエリによって Schema 変更無しで対応、みたいなケースが多いです。REST なら新しいエンドポイント追加するか、クライアント側で API を複数回叩いてパフォーマンスを悪化させるかみたいなことになりがち。もちろん GraphQL は GraphQL で N+1 問題やらキャッシュやら問題はありますが、柔軟なクエリによって追加対応無しにして本来プロダクトでやりたかったことに集中できるのは強いメリットだと思っています。

Hono

言わずと知れた軽量なフレームワークです。紹介記事は世にたくさんあるので、ここでは割愛します。

https://github.com/honojs/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 ミドルウェアが公式で用意されています。

https://github.com/honojs/middleware/tree/main/packages/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_v2fs を含めた多くの Node.js API に対するポリフィルが追加されたので、このあたりのライブラリが動かない問題は解消されていきそうではあります。(とはいえバンドルサイズが増えてしまうのは少し気になるところ)

https://blog.cloudflare.com/more-npm-packages-on-cloudflare-workers-combining-polyfills-and-native-code

まとめ

Hono で GraphQL サーバーを構築してみましたが、非常に簡単でした。有名どころの機能であればミドルウェアで提供されていることが多いので、簡単に導入できるのが Hono のいいところですね。

参考

https://github.com/yusukebe/ramen-api
https://github.com/honojs/middleware

GitHubで編集を提案
Gemcook Tech Blog
Gemcook Tech Blog

Discussion