Open jsangilve opened 5 years ago
Thanks for opening apollographql/apollo-server#3358, but I've closed it until we can discuss it a bit more. I'm curious β given the fact that subscriptions aren't supported by Apollo Gateway β if you can provide more details on the use-case where this does more than move failure from one point to another.
Elaborating: Execution of a graph with subscriptions in it is still going to be problematic, and we don't suggest exposing downstream services on their own so it feels like this just moves a failure from an earlier point to a later point, which seems like it sets false expectations for a developer which might result in disappointment after they've already put time into it.
Hey @abernix, thanks for taking the time to review the PR and look into this issue.
We have been using Apollo Federation since version 0.6.x. Our architecture is composed by different micro-services exposing GraphQL APIs; these APIs are composed together by the Apollo Gateway.
That's our basic setup β probably the most common between teams adopting Apollo Federation β and it worked, until we needed to provide real-time updates to our clients. We liked the idea of providing clients with all the info they needed through a single GQL Schema. However, given that Apollo Gateway does not support subscriptions, we looked for alternatives.
There are many ways, but I wrote down 4 different ways to overcome this issue:
We decided to try 3, because it allowed us to give a single GQL Schema to our clients, while keeping the responsibility of defining the schema to the downstream services. Furthermore, considering that subscription resolvers were really simple β just some basic filtering based on the input parameters β we dynamically generated the resolvers after calling gateway.load()
.
Last week I updated to the latest version of Apollo Gateway and found the problem described on this issue. Having Subscription types in the downstream services causes a GraphQLSchemaValidationError
.
GraphQLSchemaValidationError: [accounts] Subscription -> `Subscription` is an extension
type, but `Subscription` is not defined
The error is confusing because it doesn't give a clue about Subscription not being supported by Apollo Gateway. In fact, it's actually not fully related and that's why I open the PR.
IMHO, given that Apollo Gateway doesn't support subscriptions, I would have expected the following behaviour:
If subscriptions are set to false, as described in the docs (see below), Apollo Server would just remove any Subscription type from the Federated Graph.
// https://www.apollographql.com/docs/apollo-server/federation/implementing/
const server = new ApolloServer({
gateway,
// Currently, subscriptions are enabled by default with Apollo Server, however,
// subscriptions are not compatible with the gateway. We hope to resolve this
// limitation in future versions of Apollo Server. Please reach out to us on
// https://spectrum.chat/apollo/apollo-server if this is critical to your adoption!
subscriptions: false,
});
Otherwise, the subscription type would be composed into the Federated graph and a warning
explaining that Subscriptions won't work is logged.
Reasoning: It would be easier to adopt Apollo Gateway if teams using Apollo Server don't need to change anything on the existing services (unless they want to extend other service's types), and they should only know that subscriptions won't work at the Gateway (the warning would make this clear).
As explained above, there are alternative to get subscriptions working, but that's completely optional.
Once subscriptions are supported by Apollo Gateway, the warning is removed and teams using Apollo Gateway would need to decide whether they expose them through the gateway or not (subscriptions: false
).
I created a Codesandbox forking James Baxley's gateway example. You will need to fork it and change something on index.js
to trigger the reload and see the GraphQLSchemaValidationError
in the terminal. I had to manually load the Gateway to avoid the error thrown when gateway
is defined and subscription is not false
.
https://codesandbox.io/s/federation-gateway-error-with-subscriptions-6s7bt
Edit: the GraphQLSchemaValidationError
is thrown, regardless of Apollo Server initialized with gateway
and subscription: false
properties: https://codesandbox.io/s/federation-gateway-without-loading-manually-hwzbl
I get this error without subscription. I'm at the first stage of debugging this so I can't provide much more info.
It only occurs in production (I can't reproduce locally yet), with pm2 running multiple instances in cluster mode.
'[tracker] Registration ->
Registration
is an extension type, butRegistration
is not defined in any service'
Workaround for this issue is to expose _service
query
with sdl property only with Queries and Mutations without augmenting schema from @apollo/federation
import { GraphQLObjectType, GraphQLSchema, GraphQLString, printSchema } from 'graphql';
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: () => ({
_service: {
type: new GraphQLObjectType({
name: 'GraphqlFederation',
fields: () => ({
sdl: {
type: GraphQLString,
},
}),
}),
resolve: () => ({
sdl: printSchema(
new GraphQLSchema({
query: schema.getQueryType(),
mutation: schema.getMutationType(),
})
),
}),
},
}),
}),
});
With this approach you can have 1 Subscription server providing Pub/Sub capabilities and multiple Federated graphs. The client will subscribe to this one particular server and for queries and mutation you can use ApolloGateway.
Regards!
We encountered same issue with Subscriptions.
@abernix our use-case is that we use federation for queries & mutations, while subscriptions are served by separate endpoint. But we still want to serve combined schema to the playground (graphiql)
So we try to run composeAndValidate()
with schemas from all services and get error above
@tot-ra We understand and we continue to investigate ways to improve the options we offer for employing Subscriptions and taking advantage of Federation. Today, our only concrete suggestion is offered in this blog post.
@abernix yes, we've implemented same thing Mandi is doing. It doesn't solve the problem with schema validation though, because she is not running composeAndValidate
. She is just merging gateway schema with built-in subscriptions https://github.com/apollosolutions/federation-subscription-tools/blob/main/src/utils/schema.js#L27
What we want is to validate & register subscription schema in our schema-registry - for audit, naming collisions & codestyle checks. But since we rely on composeAndValidate
it blocks us.
Hi. We are using Managed federation and we also need Subscriptions in our federated graphs. I've managed to implement them on our Apollo Gateway by following this tutorial https://www.apollographql.com/blog/backend/federation/using-subscriptions-with-your-federated-data-graph/ and it works.
However the problem is in our CI/CD pipeline we cannot publish/check a subgraph that contains Subscription type into Apollo Studio (registry). Previously we were dynamically removing Subscription type from schema we were about to check/publish in our CI/CD, it was lame but it worked... But since now we actually need to have Subscription in our schema we cannot do it anymore and we are stuck with following error we get from Rover:
Checking the proposed schema for subgraph ident against *****
error[E029]: Encountered 1 build error while trying to build subgraph "*" into supergraph "*****@production".
Caused by:
Encountered 1 build error while trying to build the supergraph.
EXTENSION_WITH_NO_BASE: [ident] Subscription -> `Subscription` is an extension type, but `Subscription` is not defined in any service
The changes in the schema you proposed for subgraph ident are incompatible with supergraph *****@production. See https://www.apollographql.com/docs/federation/errors/ for more information on resolving build errors.
I've investigated the Rover code and it seems the error originates from https://graphql.api.apollographql.com/api/graphql
which is beyond our control :)
Is there a way to bypass this error while still being able to have Subscription in federated schema on Apollo Studio?
having waited for subscriptions support on federation for a while now β³ , i was instead able to put together a small library implementing federation with subscriptions (the way we'd hoped for, without a separate service just for subscriptions). was able to get it working using schema-stitching & graphql-tools, it's basically just transforming federation SDL into schema-stitching SDL and using websockets across the gateway & subgraphs: https://github.com/sammysaglam/federation-with-subscriptions
hope that helps
I just second to @tot-ra we have exactly the same use case with the difference we use Rover / Apollo Studio.
What we want is to validate & register subscription schema in our schema registry.
Question to you @tot-ra, have you been able to overcome it in your solution? Looks pretty dope! π
I get this error without subscription. I'm at the first stage of debugging this so I can't provide much more info.
It only occurs in production (I can't reproduce locally yet), with pm2 running multiple instances in cluster mode.
'[tracker] Registration ->
Registration
is an extension type, butRegistration
is not defined in any service'
Did you resolve this issue? I am currently the same
When a federated service's schema contains a
Subscription
type and it's loaded by the Apollo Gateway, the following error is returned:I understand Subscriptions aren't supported by Federation yet, but having them in the downstream service shouldn't affect the creation of the federated graph.
While debugging the problem, I realized the Gateway was processing the Subscription as an extension type (the same way it does with Query/Mutation), but it's not adding an empty definition type for
Subscription
.To reproduce it, just run the federation demo adding a
Subscription
to theaccounts
service:Fork including the change above: https://github.com/jsangilve/federation-demo/blob/wip/example_with_subscription/services/accounts/index.js