😀

GraphQLスキーマを外部ファイルとして読み込む方法

2023/07/01に公開

はじめに

バックエンドの開発中にsrc/server.tsに記述されたスキーマを切り分けたいと考え、schema.graphqlにスキーマを移したが、既存のpathfsで読み込むのは釈然としなかったため、その方法を調べたり、実装していたら、案外と時間を取られたので記事にしたいと思います。

ライブラリの導入

まずは、.graphqlを読み込むために、以下のライブラリを導入します。

yarn add @graphql-tools/graphql-file-loader @graphql-tools/load @graphql-tools/schema

スキーマファイルに切り分け

次にスキーマを.graphqlに切り分けます。

scheme.graphql
type Query {
  info: String!
  feed: [Link]!
}

type Mutation {
  post(url: String!, description: String!): Link!
}

type Link {
  id: ID!
  description: String!
  url: String!
}

:::note info
server.tsの記述
:::

server.ts
import { ApolloServer } from '@apollo/server'
import { startStandaloneServer } from '@apollo/server/standalone'
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader'
import { loadSchemaSync } from '@graphql-tools/load'
import { addResolversToSchema } from '@graphql-tools/schema'
import { join } from 'path'

import type { Link } from './types/Link'

const links: Link[] = []

const schema = loadSchemaSync(join(__dirname, './schema.graphql'), {
  loaders: [new GraphQLFileLoader()],
})

// リゾルバー関数
const resolvers = {
  Query: {
    info: () => 'HackerNewsクローン',
    feed: () => links,
  },

  Mutation: {
    post: async (_: unknown, args: { description: string; url: string }) => {
      let idCount = links.length

      const link = {
        id: `link-${idCount++}`,
        description: args.description,
        url: args.url,
      }

      links.push(link)

      return link
    },
  },
}

const schemaWithResolvers = addResolversToSchema({ schema, resolvers })
const server = new ApolloServer({
  schema: schemaWithResolvers,
})

const startServer = async () => {
  const { url } = await startStandaloneServer(server, {
    listen: { port: 4000 },
  })
  console.log(`🚀  Server ready at: ${url}`)
}

startServer()

まずloadSchemaSyncを使用してshcema.graphqlを読み込み、GraphQLスキーマを同期的にロードします。

const schema = loadSchemaSync(join(__dirname, './schema.graphql'), {
  loaders: [new GraphQLFileLoader()],
})

続いてaddResolversToSchemaを使用してスキーマにリゾルバーを追加します。

const schemaWithResolvers = addResolversToSchema({ schema, resolvers })

最後にApolloServerインスタンスにスキーマとリゾルバーを渡すことで、外部ファイルのGraphQLスキーマを読み込み、サーバーに渡し、起動することができます。

const server = new ApolloServer({
  schema: schemaWithResolvers,
})

参考文献

GraphQLスキーマを外部ファイル化する

Discussion