I'm having a problem with running GraphiQL on AWS lambda. When I make a query I receive
{
"message": "Forbidden"
}
as a response.
Response Headers
content-length:24
content-type:application/json
date:Tue, 18 Apr 2017 18:36:56 GMT
status:403
via:1.1 0e8771af788075ec65db839e649274c4.cloudfront.net (CloudFront)
x-amz-cf-id:AWV24_u97BrxUf5IEtuE0rdBOKh_xoijNy79pbSKpsRlzblF3VkTdA==
x-amzn-errortype:ForbiddenException
x-amzn-requestid:ffcea8fc-2465-11e7-9f34-1f26a4ebd9d4
x-cache:Error from cloudfront
The problem is only with GraphiQL. The GraphQL endpoint is working correctly. It's hard to tell what's a source of the problem because there are no CloudWatch logs. It looks like lambda function is never called.
I'm using Serverless to deploy lambda functions, but I don't think it's a case here as the GraphQL endpoint is working correctly. When I'm testing GraphiQL endpoint locally using serverless-offline everything works as expected.
Could you give me some tip on how to investigate this problem?
If there are no CloudWatch logs you are correct to assume that the lambda function is not running. You can always run the lambda function from the API Gateway console to make sure it is handling the request correctly.
A forbidden response is the default error when the API Gateway has not been configured for that endpoint. Could be a typo or using the wrong HTTP method. Take a look at the API Gateway console and ensure the endpoints are correct. GraphiQL should be using the GET method.
You can post your serverless config and I can take a look or check out this known working config:
https://github.com/apollographql/graphql-server/issues/332#issuecomment-288417312
@soda0289 thanks for the fast reply. Testing lambda function from the API Gateway console is not needed as I said GraphQL endpoint works correctly. However, I did test for POST and GET requests and both work properly. The only problem is that when request comes from the GraphiQL, then it does not work.
My SLS config is following:
GraphQL:
handler: handlers.graphql
events:
- http:
path: graphql
method: get
cors: true
- http:
path: graphql
method: post
cors: true
GraphiQL:
handler: handlers.graphiql
events:
- http:
path: graphiql
method: get
cors: true
and handlers.js
const server = require('graphql-server-lambda');
module.exports.graphql = function(event, context, callback) {
const callbackFilter = (err, output) => {
output.headers['Access-Control-Allow-Origin'] = '*';
callback(err, output);
};
const handler = server.graphqlLambda({
schema: require('./lib/schema')
});
return handler(event, context, callbackFilter);
};
module.exports.graphiql = server.graphiqlLambda({
endpointURL: '/graphql'
});
Ah my bad. I found problem. In the GraphiQL config we have to provide endpointURL with the stage :)
module.exports.graphiql = server.graphiqlLambda({
endpointURL: '/dev/graphql'
});
and not
module.exports.graphiql = server.graphiqlLambda({
endpointURL: '/graphql'
});
It's actually how it's done in the example in README, but maybe it's worth noting in docs? What do you think? I can add proper info if needed.
@jagi Thanks for giving me more details.
I was just responding with more details. Glad you fixed it. I will make an update to the README. Thanks for the suggestion.
Looks like this has been resolved. If there's a way we can make this easier to debug, please consider making a PR! 馃檪
Hello, It's possible to show me how you build your schema ?
const schema =
type Query {
hello: String
}
;
const resolver = {
Query: {
hello: () => 'Hello World',
},
};
const myGraphQLSchema = graphqlTools.makeExecutableSchema({
typeDefs: schema,
resolvers: resolver,
});
It's correct ?
@ducmaxime are you having the same problem as I did or you're just asking a random question here? Generally, your code looks correct.
used this following settings to combine graphql, graphiql(playground) endpoint to one
functions:
graphql:
handler: src/server.default
memorySize: 256
events:
- http:
path: ${self:provider.stage}/graphql
method: post
cors: true
- http:
path: ${self:provider.stage}/graphql
method: get
cors: true
import { ApolloServer } from 'apollo-server-lambda';
import { v1 as neo4j } from 'neo4j-driver';
import schema from './graphql/schema';
const driver = neo4j.driver(
process.env.NEO4J_URI,
neo4j.auth.basic(process.env.NEO4J_USER, process.env.NEO4J_PASSWORD),
);
const server = new ApolloServer({
schema,
context: ({ req }) => ({
driver,
req,
}),
playground: {
settings: {
'editor.cursorShape': 'line',
},
},
});
const handler = server.createHandler();
export default handler;
Most helpful comment
Ah my bad. I found problem. In the GraphiQL config we have to provide endpointURL with the stage :)
and not
It's actually how it's done in the example in README, but maybe it's worth noting in docs? What do you think? I can add proper info if needed.