apollographql / apollo-server

🌍  Spec-compliant and production ready JavaScript GraphQL server that lets you develop in a schema-first way. Built for Express, Connect, Hapi, Koa, and more.
https://www.apollographql.com/docs/apollo-server/
MIT License
13.75k stars 2.03k forks source link

Cannot query field "_service" on type "Query" #3419

Closed Kwadz closed 4 years ago

Kwadz commented 4 years ago

I'm using Apollo Federation to connect to a GraphQL server made with Drupal GraphQL.

So I configured the gateway:

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

const gateway = new ApolloGateway({
  serviceList: [
    { name: 'content', url: 'http://gims_content_nginx/content' }
  ]
});

(async () => {
  const { schema, executor } = await gateway.load();

  const server = new ApolloServer({ schema, executor });

  server.listen().then(({ url }) => {
    console.log(`🚀 Server ready at ${url}`);
  });
})();

But when I start the server I get:

{ message: 'Cannot query field "_service" on type "Query".',
  extensions: { category: 'graphql' },
  locations: [ { line: 1, column: 30 } ] } 0 [ { message: 'Cannot query field "_service" on type "Query".',
    extensions: { category: 'graphql' },
    locations: [ [Object] ] } ]
(node:1) UnhandledPromiseRejectionWarning: Error: Apollo Server requires either an existing schema, modules or typeDefs
    at ApolloServer.initSchema (/usr/src/app/node_modules/apollo-server-core/dist/ApolloServer.js:239:23)
    at new ApolloServerBase (/usr/src/app/node_modules/apollo-server-core/dist/ApolloServer.js:201:30)
    at new ApolloServer (/usr/src/app/node_modules/apollo-server-express/dist/ApolloServer.js:58:9)
    at new ApolloServer (/usr/src/app/node_modules/apollo-server/dist/index.js:23:9)
    at /usr/src/app/gateway.js:13:18
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
wmertens commented 4 years ago

I have the same problem. It looks like these are added by apollo-federation and apollo-gateway assumes they are always there.

If you're trying to forward to a third-party graphql, that won't work :(

brandonwkipp commented 4 years ago

I find myself in the same situation, it would be nice if we didn't have to do this, especially since some of these 3rd party graphql services are behind walls we don't control :(

wmertens commented 4 years ago

I wound up implementing it with the "deprecated" schema stitching. It turns out that there's nothing preventing you from doing that, except that the necessary helpers now live in graphq-tools.

All you're doing is creating a Link, using that to fetch and wrape the remote schema, turning it into a local schema, and then merging it with your or other schemas. As long as you don't need the "foreign key" functionality of federation, this should always work.

Therefore I think the docs should be updated to mention this.

ztolley commented 4 years ago

I had the same and it really defeats what I needed. I just want to setup a simple gateway to route requests and merge results and thought that is what gateway was for.

@wmertens Do you have any examples or good places to explain how to do the stitching?

wmertens commented 4 years ago

@ztolley actually the documentation is still valid, and only needed some slight tweaks #3449

ztolley commented 4 years ago

I found an excellent article and created a proof of concept that works perfectly. So I'll stick with stitching for now until it's supported by Sangria, Graphene and all the other libraries, not just Apollo

abernix commented 4 years ago

The downstream services in a federated architecture must implement the federation specification.

Many GraphQL servers have already implemented the federated specification already, including graphql-java, Ariadne, WPGraphQL and Graphene (via graphene-federation). Others are discussing it, including Sangria, quite recently.

wmertens commented 4 years ago

@abernix why can't the federation support be optional, and if it's missing the assumption is that all federation metadata is empty, so federation falls back to simple stitching?

brandonwkipp commented 4 years ago

@Kwadz FWIW, I abandoned using Drupal/GraphQL in favor of wrapping the Drupal RestUI module with Apollo Rest DataSource. I also wrapped another 3rd party api with the same package, works much better for our team than mucking around in PHP 🤷‍♂

Apollo Rest Datasources can be wrapped with the "buildFederatedSchema" function from the Apollo Federation package, automatically configuring the federation specification for you.

mwawrusch commented 4 years ago

Running into this issue now with faunadb downstream. Very annoying.

maurocolella commented 3 years ago

For anyone still struggling with this, check out: https://github.com/0xR/graphql-transform-federation

Which makes good use of graphl-tools for remote schemas to make it possible to seamlessly federate and augment schemas not designed for Apollo.

Your mileage might vary, but thanks to that project, I've been able to bring a complex remote schema on board of our federated graph. Took me just a couple of hours.

luijar commented 2 years ago

FYI for anyone stumbling into this and trying to figure it out. That project is out of date and doesn't work with latest Apollo libraries. I'm going to try to take that and see if I can re-engineer it so that I can federate over an existing schema (which I can't change) with latest Apollo server + Gateway