maybe daily dev notes

私の開発日誌

TypeScriptのcode-firstなGraphQL開発ツール比較: TypeGraphQL vs Nexus vs Pothos

GraphQLサーバーを開発する際は、まず schema-first か code-first かを決めることになるでしょう。前者はまず graphql.schema を手書きし、そこから言語固有のコードを生成する方法です。後者は言語固有のコードを書いてから、 graphql.schema を生成する方法です。

今回2つのどちらが良いかは議論しませんが、後者の code-first & TypeScriptでGraphQL開発をする場合、ライブラリの選択肢がいくつかあります。この記事では、それらのライブラリの特徴をまとめます。特に以下の観点で比較します:

  • Prismaとの連携: 私がTypeScriptでウェブ開発するときはORMのPrismaをよく使います。GraphQLと組み合わせる上では、型定義の重複やN+1問題を回避するため、ライブラリ間の連携は重要です。
  • 開発の活発さ: 将来的にライブラリがDeprecateされるリスクはできるだけ避けたいものです。今のメンテナンスの活発具合でこのリスクを占います。

特徴

ということで見ていきましょう。今メジャーなcode-first GraphQLライブラリは3つあります。

1. TypeGraphQL

github.com

Nest.jsTypeORMと同様に、TypeScriptのデコレータ記法をベースにしたフレームワークです。デコレータ記法は今流行りのフロントエンドライブラリではほとんど使わないので、好みが分かれるところかもしれません。

Prismaとの連携は TypeGraphQL Prisma というインテグレーションが用意されています。結構大胆で、何も設定しなくても、Prismaで定義したすべてのテーブルのCRUDゾルバーを勝手に実装してくれます。微調整も可能な模様。ただし、ORMとしては同じデコレータ記法を使うTypeORMのほうが相性良さそうに思います。

開発の活発さについて、GitHub上では一見現状の最終リリースが2020/11/5と停滞しているように見えます。しかし、実は去年v1.2.0 RCをプレリリースし、また今はv2のベータの開発を進めているようです。ほぼ作者一人の個人プロジェクトなのでやや今後に不安を覚えますが、少なくともスポンサーは複数付いています。

Contribution数はほぼ一人が支えている

正直私自身はこれをあまり使ってないので深いことは書けません。

2. Nexus

github.com

Nexus organizationメンバー3人中2人がPrismaの人という、Prismaと密接なつながりを持っているフレームワークです。TypeGraphQLとは異なりデコレータは一切使わず、コードの雰囲気もどことなくPrismaと似ています。

Nexusは実行時にTypeScriptの型定義ファイルを生成します。このため、開発時は以下のようにNexusサーバーを常駐させることが推奨されています。この仕様のため、エディタでの型チェックの反映がワンテンポ遅いという欠点もあります。

# ts-node-devで常駐させる
ts-node-dev --transpile-only --respawn nexus-server.ts

Prismaと連携するにはnexus-prisma ライブラリを利用します。前身の nexus-plugin-prisma ライブラリもあるのですが、こちらは既に開発終了で deprecated です。

ただし nexus-prisma も若干雲行きが怪しく、2022半ば頃は開発が停滞していたようです。そんな中、2022/10からメンテナンスの主体がPrismaからコミュニティに移管されつつあります。移管先は現状開発者一人のため開発速度が大きくブーストされるかは不透明ですが、今は過渡期のため当面状況を見守る必要があるでしょう。

Nexus自体も生存確認のIssueが立つ程度には開発が活発ではありません。後述のPothosに移行するためのツールを作る開発者もいるなど、穏やかではない状況です。また、メインのメンテナであるtgriesserさんが後述のPothosに感心し、NexusからPothosへの漸進的な移行方法を提供したいとも発言しています。

上記を考慮すると、今のままではNexusがユーザー数を維持・拡大する可能性は低いと推測されます。ひとまずは公式声明を待ちたいですが、当面は新規採用を控えるのが無難かもしれません。

3. Pothos

github.com

初版のリリースが2020/7と3つの中では最も若いライブラリです。元はGiraphQLという名前でしたが、視認性や検索性の問題で改名したようです。

記法はNexusとよく似ており、TypeGraphQLのようなデコレータ記法は用いません。このため、上記の通りNexusからPothosに移行する動きもあるようです。 また、謳い文句によればランタイムのオーバーヘッドがなく軽量で高速なことが売りのようです。コード生成にも頼らないため、Nexusよりも型チェックが俊敏です。

Prismaとの連携も容易で、プラグインが用意されています。密接にPrismaと統合されており、リゾルバーの中で宣言的にPrismaのクエリを書くことも可能です。

ただし、個人的にはPrisma連携で一つつらみがありました: こちらで議論されているのですが、Prismaの型を持ってくる時にデータ型やnullabilityを改めて指定する必要があり、Prisma側とコードの重複が生じる点です。ここはNexusやTypeGraphQLのほうがスマートに書けます。

// Prismaの型定義
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
}

// PothosのObject定義
 builder.prismaObject('User', {
  fields: (t) => ({
    id: t.exposeID('id'),
    email: t.exposeString('email'),
    name: t.exposeString('name', { nullable: true }),
  }),
});

開発は明らかに活発で、他の追随を許さない勢いでバージョンアップが重ねられています。今はhayesさんの個人開発なのがやや不安ですが、後述の通りユーザー数がここ1年で激増しているので、モチベーション高く開発されているようです。今のところは楽観視できるでしょう。

npmダウンロード数も比べてみましょう。緑がTypeGraphQL、オレンジがNexus、青がPothosです。全体の数はTypeGraphQL > Nexus > Pothosですが、ここ1年の伸び率は真逆でPothos > Nexus > TypeGraphQLです。

@pothos/core vs nexus vs type-graphql | npm trends

Pothosはまだユーザー数は少ないものの指数関数的な成長です。性能の良さや開発の活発さが評価されているのでしょう。Nexusの動向やTypeGraphQL v2の出来次第で、今後更に伸びるのではないでしょうか。

Nexusも2021の後半勢いづいていますが、こちらの理由は不明です。今後はPothosへの置き換えが進んでいく可能性も高いと思われます。

TypeGraphQLは2020/11以降大きなアップデートもないため、線形な成長率です。今後v2がリリースされれば、また変化が見られるでしょう。

考察

ということで、どれを選ぶべきでしょうか。

私個人の意見としては、デコレータ記法がなじまないのでTypeGraphQLはNG、またNexusは先行きが不安のためNGで、より将来性を感じるPothosを選びます。ここはまだ正解がないので、各々が考える必要があるでしょう。答え合わせは半年後になるでしょうか。

また、この選択をする上では開発体験も重要なファクターです。ここは主観にもよるところがあるので、3つのライブラリで簡単なGraphQL APIを実際に作ってみて、体験を評価することをおすすめします。

まだ私自身もGraphQLを使い始めたばかりなので、もう少しPothos or Nexusをやり込んだら再び記事を書きたいと思います。以上、TypeScript x GraphQL x code-firstなライブラリ3つの比較でした。