Invalid value for type ID, cannot be converted to AST

Github

I am testing out gateway with two services (users, todos)

If I query a user with with an id as the argument directly from service-users (localhost:5001/) in the sandbox everything works fine.

query

query Query($userId: ID!) {
  user(id: $userId) {
    name
  }
}

variables

{
  "userId": "1"
}

If try this same query from my gateway (localhost:5000/) I get an error.

  "errors": [
    {
      "message": "Invalid value for type ID, cannot be converted to AST: Variable { name: 'userId' }",
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Invalid value for type ID, cannot be converted to AST: Variable { name: 'userId' }",

Below is my code for the gateway + services. I’m fairly new to gql and this is just a simple example I’ve built to help my understanding. My data is in local json files.

gateway:

const { ApolloGateway, IntrospectAndCompose } = require("@apollo/gateway");
const { ApolloServer } = require("apollo-server");

const start = async (_) => {
  const gateway = new ApolloGateway({
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { url: "http://localhost:5001", name: "service-users" },
        { url: "http://localhost:5002", name: "service-todos" },
      ],
    }),
  });

  const server = new ApolloServer({
    gateway,
  });

  server.listen(process.env.PORT).then(({ url }) => {
    console.log(`Gateway started on: ${url}`);
  });
};

start();

service-users

const { ApolloServer, gql } = require("apollo-server");
const todos = require("./todos.json");
const { buildSubgraphSchema } = require("@apollo/subgraph");
const { ApolloServerPluginInlineTraceDisabled } = require("apollo-server-core");

const typeDefs = gql`
  type Todo {
    userId: ID!
    id: ID!
    title: String!
    completed: Boolean!
  }

  extend type User @key(fields: "id") {
    id: ID! @external
    userTodos: [Todo!]!
  }

  type Query {
    allTodos(id: ID): [Todo!]!
  }
`;

const resolvers = {
  Query: {
    allTodos: (root, { id }) =>
      !id ? todos : todos.filter((todo) => todo.id === id),
  },
  User: {
    userTodos: (user) => todos.filter((todo) => todo.userId === user.id),
  },
};

const server = new ApolloServer({
  schema: buildSubgraphSchema({ typeDefs, resolvers }),
  plugins: [ApolloServerPluginInlineTraceDisabled()],
});

server.listen(process.env.PORT).then(({ url }) => {
  console.log(`Todos service started on: ${url}`);
});


service-todos

const { ApolloServer, gql } = require("apollo-server");
const todos = require("./todos.json");
const { buildSubgraphSchema } = require("@apollo/subgraph");
const { ApolloServerPluginInlineTraceDisabled } = require("apollo-server-core");

const typeDefs = gql`
  type Todo {
    userId: ID!
    id: ID!
    title: String!
    completed: Boolean!
  }

  extend type User @key(fields: "id") {
    id: ID! @external
    userTodos: [Todo!]!
  }

  type Query {
    allTodos(id: ID): [Todo!]!
  }
`;

const resolvers = {
  Query: {
    allTodos: (root, { id }) =>
      !id ? todos : todos.filter((todo) => todo.id === id),
  },
  User: {
    userTodos: (user) => todos.filter((todo) => todo.userId === user.id),
  },
};

const server = new ApolloServer({
  schema: buildSubgraphSchema({ typeDefs, resolvers }),
  plugins: [ApolloServerPluginInlineTraceDisabled()],
});

server.listen(process.env.PORT).then(({ url }) => {
  console.log(`Todos service started on: ${url}`);
});