Open luchillo17 opened 1 year ago
Are you sure the server
variable's promise is being fulfilled before passing server
to startServerAndCreateNextHandler
? It looks like you're doing top-level await, which as far as I know isn't supported in Next.js.
It is in experimental flags in the config for webpack, should work based on this comment 2 years back, basically it's webpack that gives the support: https://github.com/vercel/next.js/discussions/11185#discussioncomment-128562
If it were to be the await, why does it work when I move this code to the pages/api/graphql.ts
? (of course I have to remove the GET
& SET
functions).
The biggest difference here would be the export default in the Pages
router vs the export of the 2 handlers in the App
router, I do believe I followed the steps, could topLevelAwait
be having unintended consequences here?
luchillo17, I have the same problem as you. Page Router works fine when using top level "await". But when I use app router, I get almost the same terminal output as you.
@skn437 Have you tried without the top level await part? I can't remove it because Neo4j generates the schema with a promise so...
@skn437 Have you tried without the top level await part? I can't remove it because Neo4j generates the schema with a promise so...
Me as well. I also use Neo4j. It needs "await" to generate Schema. So I can't remove it.
According to this it seems like top-level await doesn't work in the app directory.
I haven't tried this so it might not work, but you might be able to fulfill the promise when the first request comes in like this:
import { startServerAndCreateNextHandler } from '@as-integrations/next';
import { getApolloServer } from '@graph-meister/neo4j-apollo';
import { NextRequest } from 'next/server';
const typeDefs = `#graphql
type Movie {
title: String
tagline: String
released: Int
actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN)
directors: [Person!]! @relationship(type: "DIRECTED", direction: IN)
}
type Person {
name: String
born: Int
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
`;
let handler = null;
let server = null;
export async function GET(request: NextRequest) {
if (!server) {
server = await getApolloServer(typeDefs);
handler = startServerAndCreateNextHandler(server);
}
return handler(request);
}
export async function POST(request: NextRequest) {
// might need the same code here
return handler(request);
}
Oh, bit ugly but as long as it does work, so we store the instance on the first available request and reuse it as long as it exists in the global variable.
I wonder if the schemaLink
will help as mentioned here: https://github.com/apollographql/apollo-client-nextjs/issues/31#issuecomment-1584349812
It worked perfectly, though I wonder if this could be considered a production-ready setup...
let server: ApolloServer<BaseContext>;
let handler: ReturnType<typeof startServerAndCreateNextHandler>;
const getServerHandler = async () => {
server ??= await getApolloServer(typeDefs);
handler ??= startServerAndCreateNextHandler(server);
};
export async function GET(request: NextRequest) {
await getServerHandler();
return handler(request);
}
export async function POST(request: NextRequest) {
await getServerHandler();
return handler(request);
}
Thanks a lot...It works...
Maybe mentioning this in the README for working around top-level await?
Handler in App router TypeError 'setup'
While using Next 13.4.1, tried to use the app router to expose graphql server under
app/graphql/route.ts
, it gives errors, it does work if I move it to the deprecatedpages
router underpages/api/graphql.ts
, did try the experimental flag on thenext.config.js
file to no avail.Code
Environment
Terminal output