🕌
Next13の app router で GraphQL 使ったときに遭遇したエラーの解決集
Next.jsでGraphQLの勉強を始めようと思って下記サイトを参考に環境を構築してたらたくさんのエラーに合ったのでその解決法を記載します。
環境構築時のスタックは下記になります。
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__)')
- 対処法
- app\page.tsx にuse client を追記
- Next13 App Router では、ssrが主体のため、useフックスを使うにはファイル先頭に明示的な記載が必要になったらしい
- https://stackoverflow.com/questions/76188431/error-cannot-read-properties-of-undefined-reading-symbol-apollo-context
http://localhost:3000/api/graphql 400 (Bad Request)
エラー2 : POST- 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
調べてみると下記サイト発見。
- https://zenn.dev/yu_undefined/articles/8cdc18028b908d
- apollo-server-micro は非推奨で且つ、@as-integrations/next というライブラリーをかませる必要があるみたいだった。
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’
- 最後によくわからんエラーに遭遇。
- とりあえずググって下記サイト通りにライブラリーをインストールしたら治った
- https://flaviocopes.com/fix-module-not-found-cant-resolve-encoding-in-nextjs/
yarn add encoding
Discussion