3

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"
  }
}
  • I'm curious if the `serverless deploy` command run for the gateway and its result could help point you in the right direction here, did it return any errors or appear out of the ordinary? Does each lambda have the correct CORS headers? – Kyle O'Brien Jun 21 '22 at 18:41

0 Answers0