I'm trying to set up a test federated GraphQL instance using serverless lambdas. Right now I have the products subgraph deployed on one lambda and the gateway deployed on another lambda. Queries to the products lambda work fine; however, making the same query to the gateway returns the below error. If I deploy a local gateway, I am able to make queries to the products subgraph - it only doesn't work through the gateway deployed in Lambda. While I have seen people online saying they have successfully implemented a GraphQL federation gateway in AWS lambda, I have not been able to find a working code base or anyone experiencing this same issue. Any insights would be much appreciated, thanks!
Error Status: 400
{
"errors": [
{
"message": "Cannot read property 'QUERY' of undefined",
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"TypeError: Cannot read property 'QUERY' of undefined",
" at QueryPlanningContext.getVariableUsages (/var/task/node_modules/@apollo/query-planner/dist/QueryPlanningContext.js:46:115)",
" at executionNodeForGroup (/var/task/node_modules/@apollo/query-planner/dist/buildQueryPlan.js:162:36)",
" at /var/task/node_modules/@apollo/query-planner/dist/buildQueryPlan.js:58:39",
" at Array.map (<anonymous>)",
" at buildQueryPlan (/var/task/node_modules/@apollo/query-planner/dist/buildQueryPlan.js:58:26)",
" at QueryPlanner.buildQueryPlan (/var/task/node_modules/@apollo/query-planner/dist/index.js:28:52)",
" at /var/task/node_modules/@apollo/gateway/dist/index.js:95:58",
" at NoopContextManager.with (/var/task/node_modules/@opentelemetry/api/build/src/context/NoopContextManager.js:36:24)",
" at ContextAPI.with (/var/task/node_modules/@opentelemetry/api/build/src/api/context.js:71:54)",
" at NoopTracer.startActiveSpan (/var/task/node_modules/@opentelemetry/api/build/src/trace/NoopTracer.js:67:28)"
]
}
}
}
]
}
Below code is for subgraph lambda
products.js
const { ApolloServer, gql } = require ('apollo-server-lambda');
const { buildSubgraphSchema } = require('@apollo/subgraph');
const products = [
{
upc: 'a1',
name: 'latte',
price: 3
},
{
upc: 'a2',
name: 'macchiato',
price: 4
},
{
upc: 'a3',
name: 'mocha',
price: 5
}
];
const typeDefs = gql`
type Product @key(fields: "upc"){
upc: String!
name: String!
price: Int
}
type Query {
product(upc: String!): Product
}
`;
const resolvers = {
Query: {
product(parent, args, context, info){
return products.find(product => product.upc === args.upc)
}
},
Product: {
__resolveReference(reference){
return products.find(product => product.upc === reference.upc)
}
}
};
const server = new ApolloServer({
schema: buildSubgraphSchema({typeDefs, resolvers})
});
exports.productsHandler = server.createHandler();
serverless.yml
service: graphqlproducts
provider:
name: aws
runtime: nodejs14.x
functions:
products:
handler: products.productsHandler
events:
- http:
path: /
method: post
cors: true
- http:
path: /
method: get
cors: true
package.json
{
"name": "graphql-poc",
"description": "GraphQL POC",
"version": "0.0.1",
"private": true,
"dependencies": {
"@apollo/federation": "^0.35.1",
"@apollo/subgraph": "^0.2.0",
"apollo-server": "^3.6.3",
"apollo-server-lambda": "^3.6.2",
"graphql": "^16.3.0"
},
"devDependencies": {},
"scripts": {}
}
Below is code for gateway lambda
index.js
const { ApolloServer } = require('apollo-server-lambda');
const { ApolloGateway, IntrospectAndCompose } = require('@apollo/gateway');
const gateway = new ApolloGateway({
supergraphSdl: new IntrospectAndCompose({
subgraphs: [
{ name: 'products', url: 'redacted' }
],
}),
});
// Pass the ApolloGateway to the ApolloServer constructor
const server = new ApolloServer({
gateway
});
exports.gatewayHandler = server.createHandler();
serverless.yml
service: graphqlgateway
provider:
name: aws
runtime: nodejs14.x
functions:
gateway:
handler: index.gatewayHandler
timeout: 20
events:
- http:
path: /
method: post
cors: true
- http:
path: /
method: get
cors: true
package.json
{
"name": "graphqlpocgateway",
"version": "0.0.1",
"description": "Gateway for graphqlpoc",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@apollo/gateway": "^0.47.0",
"apollo-server": "^3.6.2",
"apollo-server-lambda": "^3.6.3",
"graphql": "^15.8.0"
},
"devDependencies": {
"@apollo/rover": "^0.4.1"
}
}