😄
ApolloError: Response not successful: Received status code 405
はじめに
Nextjs で @apollo/server を使って GraphQLを実行していたところ、ローカル環境だと正常に動作するが、Vercelで動かすと405エラーになる問題が起きた。
import { ApolloServer } from "@apollo/server";
import { startServerAndCreateNextHandler } from "@as-integrations/next";
import { PrismaClient } from "@prisma/client";
import { readFileSync } from 'fs';
import path from "path";
const prisma = new PrismaClient();
const resolvers = {
Query: {
products: () => prisma.products.findMany(),
},
};
const typeDefs = readFileSync('src/graphql/schema.gql', { encoding: 'utf-8' });
const server = new ApolloServer({
resolvers,
typeDefs,
});
export default startServerAndCreateNextHandler(server);
コンソールだと詳細なエラーを確認できないため、VercelのLogsからログを確認したところ ↓のようなエラーが発生していることを確認できた。
どうやら readFileSync()
でのGraphQLスキーマファイルの読み込みに失敗しているようだ。
⨯ Error: ENOENT: no such file or directory, open 'src/graphql/schema.gql'
at Object.openSync
readFileSync()
でのスキーマファイル読み込みは Appllo Server の公式ドキュメント(↓) でも紹介している手法なので他の可能性が考えられる。
結論
ビルドされたファイルはVercel環境の別の場所に作られるため、指定したパスがずれてしまうようだった。そのため process.cwd()
でカレントディレクトリを取得し、ディレクトリ構造が変わっても対応できるようにする必要がある。
const typeDefs = readFileSync(schemaPath, { encoding: 'utf-8' });
ファイルを読み込む時は process.cwd()
使おうねとVercel公式ガイドにしっかり記載されていた 😇
最終的なコード
import { ApolloServer } from "@apollo/server";
import { startServerAndCreateNextHandler } from "@as-integrations/next";
import { PrismaClient } from "@prisma/client";
import { readFileSync } from 'fs';
import path from "path";
const prisma = new PrismaClient();
const resolvers = {
Query: {
products: () => prisma.products.findMany(),
},
};
const schemaPath = path.join(process.cwd(), 'src/graphql/schema.gql');
const typeDefs = readFileSync(schemaPath, { encoding: 'utf-8' });
const server = new ApolloServer({
resolvers,
typeDefs,
});
export default startServerAndCreateNextHandler(server);
Discussion