For

2023.1.16

GraphQLバックエンドの実装でNexusを使うモチベーション

前置き

GraphQLバックエンドの実装でNexusが徐々に使われ始めていて、私が携わっている案件でも採用されて実装を始めていますが、使うとどういう良いことがあるのかを理解してNexusを使うモチベーションを調べてみようと思います。

インストール数の推移

これは2023/1/16(月)時点での推移で npm trends での検索結果を利用させていただきました。



GraphQLはWeekly Downloadsが約1,000万あるので、GraphQLが採用されたプロジェクトの中でもNexusの採用数はまだまだ少ないことはわかりますが、この1年でインストール数は2倍以上になっています。

Nexusを使うモチベーション

通常のGraphQL実装は "スキーマファースト"

スキーマファーストとは以下のような流れで実装することを指します。
・GraphQL SDL(Schema Definition Language: スキーマ定義言語)を使ってスキーマを定義する
・データを処理するためのリゾルバを記述する
・スキーマとリゾルバをGraphQLサーバーに渡す

つまり、GraphQL SDLとリゾルバを実装するTypeScriptなどによる、以下のようなファイルが必要になります。

GraphQL_____schema.graphql_____type Post {
  id: ID!
  title: String!
  body: String!
}

type Query {
  posts: [Post]!
}


TypeScript_____resolver_____const Query = {
  posts: () => [
    {
      id: '1',
      title: 'My first GraphQL server',
      body: 'How I wrote my first GraphQL server',
    },
  ],
}


Nexusは "コードファースト"

Nexusを利用すると以下のようにスキーマとリゾルバを共通の言語で一度に記述できます。

TypeScript_____Nexus利用時_____import { objectType, queryType, makeSchema } from 'nexus'
const Post = objectType({
  name: 'Post',
  definition(t) {
    t.id('id')
    t.string('title')
    t.string('body')
  },
})

const Query = queryType({
  definition(t) {
    t.list.field('posts', {
      type: "Post",
      resolve: () => [
        {
          id: '1',
          title: 'My first GraphQL server',
          body: 'How I wrote my first GraphQL server',
        },
      ],
    })
  },
})
const schema = makeSchema({
  types: [Post, Query],
})


Nexusやコードファーストであるメリット

・スキーマファーストの場合はアプリケーションの規模が大きくなるにつれてスキーマ定義言語とTypeScriptの間を行き来する必要があるが、コードファーストなNexusはファイルや言語の精神的なコンテキストスイッチが不要
・TypeScriptの型とGraphQL SDLファイルを自動的に生成する機能がある
・makeSchemaがTypeScriptの型を自動生成するたび、実装がスキーマの要件を満たしているかどうか即座にエディタへフィードバックされる
・スキーマ定義言語と実装でインターフェイスなどの繰り返しの記述が不要になる

まとめ

これから採用されるプロジェクトは増えていくのかなというのと、特に提供するAPI数が多い、または多くなる想定のプロジェクトでは採用することによる恩恵が受けやすいのかなと思います。
ひとつの言語で実装できるのは実装者として嬉しいので、規模に関わらず採用することもありそうです。