How To Set Http Status Code In GraphQL
Solution 1:
Unless the GraphQL request itself is malformed, GraphQL will return a 200 status code, even if an error is thrown inside one of the resolvers. This is by design so there's not really a way to configure Apollo server to change this behavior.
That said, you could easily wire up your own middleware. You can import the runHttpQuery
function that the Apollo middleware uses under the hood. In fact, you could pretty much copy the source code and just modify it to suit your needs:
const graphqlMiddleware = options => {
return (req, res, next) => {
runHttpQuery([req, res], {
method: req.method,
options: options,
query: req.method === 'POST' ? req.body : req.query,
}).then((gqlResponse) => {
res.setHeader('Content-Type', 'application/json')
// parse the response for errors and set status code if needed
res.write(gqlResponse)
res.end()
next()
}, (error) => {
if ( 'HttpQueryError' !== error.name ) {
return next(error)
}
if ( error.headers ) {
Object.keys(error.headers).forEach((header) => {
res.setHeader(header, error.headers[header])
})
}
res.statusCode = error.statusCode
res.write(error.message)
res.end()
next(false)
})
}
}
Solution 2:
For apollo-server, install the apollo-server-errors package. For authentication errors,
import { AuthenticationError } from "apollo-server-errors";
Then, in your resolver
throw new AuthenticationError('unknown user');
This will return a 400 status code.
Read more about this topic in this blog
Solution 3:
as you can see here formatError
doesn't support status code, what you could do is create a status response type with message and status fields and return the corresponding on your resolver.
Does GraphQL require a 200 response even for failed queries / mutations?
No, if the query fails it will return null
and the error that you throw in the server side.
Solution 4:
Try adding response and setting the response status code as so, assuming your err.status is already an integer like 401 etc.:
const graphqlKoaMiddleware = graphqlKoa(ctx => {
return ({
schema,
response: request.resonse,
formatError: (err) => {
response.statusCode = err.status;
return ({message: err.message, status: err.status})},
context: {
stationConnector: new StationConnector(),
passengerTypeConnector: new PassengerTypeConnector(),
authConnector: new AuthConnector(),
cookies: ctx.cookies
}
})})
Solution 5:
Based on Daniels answer i have managed to write middleware.
import { HttpQueryError, runHttpQuery } from 'apollo-server-core';
import { ApolloServer } from 'apollo-server-express';
// Source taken from: https://github.com/apollographql/apollo-server/blob/928f70906cb881e85caa2ae0e56d3dac61b20df0/packages/apollo-server-express/src/ApolloServer.ts
// Duplicated apollo-express middleware
export const badRequestToOKMiddleware = (apolloServer: ApolloServer) => {
return async (req, res, next) => {
runHttpQuery([req, res], {
method: req.method,
options: await apolloServer.createGraphQLServerOptions(req, res),
query: req.method === 'POST' ? req.body : req.query,
request: req,
}).then(
({ graphqlResponse, responseInit }) => {
if (responseInit.headers) {
for (const [name, value] of Object.entries(responseInit.headers)) {
res.setHeader(name, value);
}
}
res.statusCode = (responseInit as any).status || 200;
// Using `.send` is a best practice for Express, but we also just use
// `.end` for compatibility with `connect`.
if (typeof res.send === 'function') {
res.send(graphqlResponse);
} else {
res.end(graphqlResponse);
}
},
(error: HttpQueryError) => {
if ('HttpQueryError' !== error.name) {
return next(error);
}
if (error.headers) {
for (const [name, value] of Object.entries(error.headers)) {
res.setHeader(name, value);
}
}
res.statusCode = error.message.indexOf('UNAUTHENTICATED') !== -1 ? 200 : error.statusCode;
if (typeof res.send === 'function') {
// Using `.send` is a best practice for Express, but we also just use
// `.end` for compatibility with `connect`.
res.send(error.message);
} else {
res.end(error.message);
}
},
);
};
}
app.use(apolloServer.graphqlPath, badRequestToOKMiddleware(apolloServer));
Post a Comment for "How To Set Http Status Code In GraphQL"