🕌

Next13の app router で GraphQL 使ったときに遭遇したエラーの解決集

2023/06/25に公開

Next.jsでGraphQLの勉強を始めようと思って下記サイトを参考に環境を構築してたらたくさんのエラーに合ったのでその解決法を記載します。
https://numb86-tech.hatenablog.com/entry/2022/03/14/203723

環境構築時のスタックは下記になります。
node : v16.15.0
"next": "13.4.6"
"graphql": "^16.6.0"
"@apollo/client": "^3.7.15"
"@apollo/server": "^4.7.4"
https://github.com/engineet-misaki/graphql_sample

上記サイトはapp routerを使ってないのでディレクトリー構造とかその辺を読み替えたりして進める必要があるから脳死でやるには注意が必要だったなあ。。
Next13から始まった app router について

エラー1 : Cannot read properties of undefined (reading 'Symbol(APOLLO_CONTEXT)')

Unhandled Runtime Error
Error: Cannot read properties of undefined (reading 'Symbol(__APOLLO_CONTEXT__)')

エラー2 : POST http://localhost:3000/api/graphql 400 (Bad Request)

  • app routerを使っているのでフォルダは、pages/api/graphql.ts ではなく、app/api/graphql/route.ts にしないといけない。
  • app routerのについての参考

エラー3 : 405 (Method Not Allowed)

  • 解決策
    apollo-server-micro は非推奨で且つ、@as-integrations/next というライブラリーをかませる必要.

  • 遭遇したエラー

クライアント側
POST http://localhost:3000/api/graphql 405 (Method Not Allowed)
サーバー側
[2] - error Detected default export in 'C:\~~~\app\api\graphql\route.ts'. Export a named export for each HTTP method instead.
[2] - error No HTTP methods exported in 'C:\~~~\app\api\graphql\route.ts'. Export a named export for each HTTP method.
  • 最初はエラー通り、関数名をHTTPメソッド名のnemed exportにして、見たけど下記のようにエラーになった。
export default async function handler()
↓
export async function POST

そしたらエラーになる

error TypeError: res.end is not a function

調べてみると下記サイト発見。

yarn add @apollo/server @as-integrations/next
削除もしとく
yarn remove micro apollo-server-micro
  • 書き換えたものが下記。
router.ts
import { NextRequest } from "next/server";
import { ApolloServer } from "@apollo/server";
import { startServerAndCreateNextHandler } from "@as-integrations/next";
import { readFileSync } from "fs";
import { join } from "path";

import { Resolvers } from "../../../graphql/dist/generated-server";

const path = join(process.cwd(), "graphql", "schema.graphql");
const typeDefs = readFileSync(path).toString("utf-8");

// いったん静的で定義
type User = { id: string; name: string };

const users: User[] = [
  { id: "1", name: "Alice" },
  { id: "2", name: "Bob" },
  { id: "3", name: "Carol" },
];

const resolvers: Resolvers = {
  Query: {
    users: () => users,
  },
};

const apolloServer = new ApolloServer({ typeDefs, resolvers });

const handler = startServerAndCreateNextHandler<NextRequest>(apolloServer, {
  context: async (req) => ({ req }),
});

export async function POST(request: NextRequest) {
  return handler(request);
}

エラー4 : Module not found: Can’t resolve ‘encoding’ in …/node_modules/node-fetch/lib’

Module not found: Can’t resolve ‘encoding’ in …/node_modules/node-fetch/lib’
yarn add encoding

Discussion