graphql-yoga
graphql-yoga copied to clipboard
How to set the server timeout
Hello,
I am using graphql-yoga to run my graphql service. What is the default timeout to graphql-yoga server? How can I set the maximum timeout on the server level?
Can someone help me here? Following is the code I am using.
const { GraphQLServer } = require('graphql-yoga');
const server = new GraphQLServer({
schema,
context: request => ({ ...request }),
middleware: [loggingMiddleware]
})
const options = {
port: 8050,
endpoint: xyzService
}
server.start(options, ({ port, endpoint }) =>
console.log(
`Server started, listening on port ${port}${endpoint} for incoming requests.`,
),
)
Do we have any resolution on it, I see graphql-yoga uses express-js internally, but how can I update the timeout of the server call.
We have a call to the view table which takes up to 5 mins runnings on the Dbeaver itself because of 5 million+ data rows. GraphQL-yoga query takes 2m as the default timeout. Is there any way we can update it?
I also had issues with the 2 minute timeout so I forked the repo and added a timeout option. It doesn't look like graphql-yoga is actively maintained anymore so I shouldn't lose much by using a forked version and maintaining it myself.
If it wasn't for me using Prisma 1 with prisma-binding, I'd just switch to apollo-server-express, where it's easy to add a timeout
const server = new ApolloServer({ typeDefs, resolvers });
const app = express();
server.applyMiddleware({ app });
app.listen({ port: 4000 }, () =>
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
).setTimeout(1000*60*10)
This, however, breaks all my field aliases on my prisma resolvers and would force me to rewrite all of my middleware functions for my resolvers.
You can increase the express
timeout in graphql-yoga
like so:
const server = new GraphQLServer({ typeDefs, resolvers });
server.start(() => console.log('Server is running on localhost:4000'))
.then(s => s.setTimeout(5 * 60 * 1000)); // 5 minutes
In this case s
is the instance of a regular node HTTP Server
or HTTPS Server
.
This issue is kinda' obsolete since Yoga v3 is server agnostic, there is no generic way of extending the timeout - it needs to be done on the server itself.
Examples
Node
import { createSchema, createYoga } from 'graphql-yoga'
import { createServer } from 'node:http'
const yoga = createYoga({ ... })
const server = createServer(yoga)
server.setTimeout(5 * 60 * 1000) // 5 minute timeout
server.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})
Express
import { createYoga } from 'graphql-yoga'
import express from 'express'
const app = express()
const yoga = createYoga({ ... })
app.use('/graphql', (req, res) => {
res.setTimeout(5 * 60 * 1000) // 5 minute timeout
yoga(req, res)
})
app.listen(4000, () => {
console.info('Server is running on http://localhost:4000/graphql')
})
Fastify
import { createYoga } from 'graphql-yoga'
import fastify from 'fastify'
const app = fastify({
requestTimeout: 5 * 60 * 1000, // 5 minute timeout
})
const yoga = createYoga({ ... })
app.route({
url: '/graphql',
method: ['GET', 'POST', 'OPTIONS'],
handler: async (req, reply) => {
const res = await yoga.handleNodeRequest(req, { req, reply })
res.headers.forEach((value, key) => {
reply.header(key, value)
})
reply.status(res.status)
reply.send(res.body)
return reply
},
})
app.listen({ port: 4000 })
console.log(`Listening on http://localhost:4000/graphql`)
Koa
import { createYoga } from 'graphql-yoga'
import Koa from 'koa'
const app = new Koa()
const yoga = createYoga({ ... })
app.use(async (ctx) => {
ctx.req.setTimeout(5 * 60 * 1000) // 5 minute timeout
const res = await yoga.handleNodeRequest(ctx.req, ctx)
ctx.status = res.status
res.headers.forEach((value, key) => {
ctx.append(key, value)
})
ctx.body = res.body
})
app.listen(4000, () => {
console.log(`Listening on http://localhost:4000/graphql`)
})
There appears to be undocumented behaviour with handleNodeRequest
.
const response = await yoga.handleNodeRequest(request, {
foo: request,
request,
});
both inputs come out as different objects:
context: async ({ request, foo }) => {
console.log('>>>', foo === request);
>>> false
For whatever reason, the request
object is being corrupted. It is supposed to have session
property, but it is undefined
. Meanwhile, foo.session
works as expected.