Reputation: 47
I am trying to launch an Apollo Server as a cloud function in typescript and want to use @cypher and @relationship directives in my typeDefs.
To use these directives I am using "@neo4j/graphql": "^3.0.0".
I am getting errors while providing schema to the apollo server. getSchema() returns a Promise but ApollServer expects a schema of type GraphQL Schema.
const neoSchema = new Neo4jGraphQL({ typeDefs });
const server = new ApolloServer({
schema: neoSchema.getSchema(),
context: ({ req }) => ({
headers: req.headers,
req,
}),
});
exports.handler = server.createHandler();
Would really appreciate it if someone can help me out here.
Upvotes: 0
Views: 904
Reputation: 3607
Apollo Server can't handle a promise at this step, and you can't do top-level awaits (unless you're on typescript.next), so you have to wrap this in another function.
If you don't memoize this, you'll create a new handler on every invocation, which opens you up to a file descriptor leak. The symptom of this is that you'll start getting timeouts for EVERYTHING (including DNS lookups), so you'll start getting ENOTFOUND
errors in your code. I've added a comment for your future generations:
const neoSchema = new Neo4jGraphQL({ typeDefs });
let _cachedHandler: ReturnType<ApolloServer['createHandler']>;
/**
* We have to be careful here that we're not creating a new server on EVERY invocation
* because that will create a file descriptor leak. Make sure you're using a memoized cache
*/
const memoizedHandler = async (event, context) => {
if (!_cachedHandler) {
const server = new ApolloServer({
schema: await neoSchema.getSchema(),
context: ({ req }) => ({
headers: req.headers,
req,
}),
});
// this is the actual handler
_cachedHandler = server.createHandler();
}
// now we can just call the handler
return _cachedHandler(event, context);
}
exports.handler = memoizedHandler;
Upvotes: 2