🙌

Next14(AppRouter)とApolloServer4系の統合 feat. Prisma

2024/02/04に公開

はじめに

本記事では、ApolloServer4系とNext.jsを統合し、AppRouterを使用した場合の記述についてのメモになります。また、一部NextAuthとPrismaも出てきますが、そちらについてはこの記事では取り扱っていません。

各種パッケージのバージョン
package.json
 "dependencies": {
    "next": "14.0.4",
    "@apollo/server": "^4.10.0",
    "@as-integrations/next": "^3.0.0",
    ...
  },
  "devDependencies": {
    "typescript": "^5.3.3",
    ...
  }

ApolloServer4系とAppRouterの設定

@as-integrations/nextのREADMEをベースにしていますが、GraphQLで使用するContextの型をapolloServerに組み込んだ構成になります。
以下のコードにあるresolvers, typeDefsはgraphql-codegenで自動生成したものです。
graphql-codegenの記事についてはこちらを参照ください。
https://zenn.dev/takumi776/articles/10476352d995f6

api/graphql/route.ts
import { ApolloServer } from '@apollo/server';
import { startServerAndCreateNextHandler } from '@as-integrations/next';
import type { NextRequest } from 'next/server';

import { resolvers, typeDefs } from '@/schema';
import type { Context as GraphQLContext } from '@/schema/context';
import { createContext } from '@/schema/context';

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

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

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

export async function POST(request: NextRequest) {
  return handler(request);
}
createContextの中身はこちら
context.ts
import type { User } from '@prisma/client';
import { getServerSession } from 'next-auth';

import { authOptions } from '@/lib/next-auth/options';
import prisma from '@/lib/prisma';

export type Context = {
  prisma: typeof prisma;
  currentUser: User | null;
};

export const createContext = async (req: NextRequest): Promise<Context> => {
  const session = await getServerSession(authOptions);
  const email = session?.user?.email;
  const currentUser = email ? await prisma.user.findUnique({ where: { email } }) : null;
  return { prisma, currentUser };
};

参照

https://www.apollographql.com/docs/apollo-server/integrations/integration-index/

Discussion