diff --git a/CHANGELOG.md b/CHANGELOG.md
index befeb9d3ebe..b289068e815 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,10 @@
[@freiksenet](https://github.com/freiksenet) in [#1003](https://github.com/apollographql/graphql-tools/pull/1003)
* Allow user-provided `buildSchema` options.
[@trevor-scheer](https://github.com/trevor-scheer) in [#1154](https://github.com/apollographql/graphql-tools/pull/1154)
+* Fix `delegateToSchema` to allow delegation to subscriptions with different root field names, allows
+ the use of the `RenameRootFields` transform with subscriptions,
+ pull request [#1104](https://github.com/apollographql/graphql-tools/pull/1104), fixes
+ [#997](https://github.com/apollographql/graphql-tools/issues/997).
### 4.0.4
diff --git a/src/stitching/delegateToSchema.ts b/src/stitching/delegateToSchema.ts
index ff6bab772e9..9f38315968b 100644
--- a/src/stitching/delegateToSchema.ts
+++ b/src/stitching/delegateToSchema.ts
@@ -125,12 +125,11 @@ async function delegateToSchemaImplementation(
// "subscribe" to the subscription result and map the result through the transforms
return mapAsyncIterator(executionResult, result => {
const transformedResult = applyResultTransforms(result, transforms);
- const subscriptionKey = Object.keys(result.data)[0];
- // for some reason the returned transformedResult needs to be nested inside the root subscription field
- // does not work otherwise...
+ // wrap with fieldName to return for an additional round of resolutioon
+ // with payload as rootValue
return {
- [subscriptionKey]: transformedResult,
+ [info.fieldName]: transformedResult,
};
});
}
diff --git a/src/test/testAlternateMergeSchemas.ts b/src/test/testAlternateMergeSchemas.ts
index e593d0028e0..a7f4b3a422a 100644
--- a/src/test/testAlternateMergeSchemas.ts
+++ b/src/test/testAlternateMergeSchemas.ts
@@ -1,7 +1,13 @@
/* tslint:disable:no-unused-expression */
import { expect } from 'chai';
-import { graphql, GraphQLSchema } from 'graphql';
+import {
+ graphql,
+ GraphQLSchema,
+ ExecutionResult,
+ subscribe,
+ parse,
+} from 'graphql';
import mergeSchemas from '../stitching/mergeSchemas';
import {
transformSchema,
@@ -9,7 +15,14 @@ import {
RenameTypes,
RenameRootFields,
} from '../transforms';
-import { propertySchema, bookingSchema } from './testingSchemas';
+import {
+ propertySchema,
+ bookingSchema,
+ subscriptionSchema,
+ subscriptionPubSub,
+ subscriptionPubSubTrigger,
+} from './testingSchemas';
+import { forAwaitEach } from 'iterall';
let linkSchema = `
"""
@@ -78,11 +91,23 @@ describe('merge schemas through transforms', () => {
(operation: string, name: string) => `Bookings_${name}`,
),
]);
+ const transformedSubscriptionSchema = transformSchema(subscriptionSchema, [
+ new FilterRootFields(
+ (operation: string, rootField: string) =>
+ // must include a Query type otherwise graphql will error
+ 'Query.notifications' === `${operation}.${rootField}` ||
+ 'Subscription.notifications' === `${operation}.${rootField}`,
+ ),
+ new RenameTypes((name: string) => `Subscriptions_${name}`),
+ new RenameRootFields(
+ (operation: string, name: string) => `Subscriptions_${name}`),
+ ]);
mergedSchema = mergeSchemas({
schemas: [
transformedPropertySchema,
transformedBookingSchema,
+ transformedSubscriptionSchema,
linkSchema,
],
resolvers: {
@@ -234,6 +259,41 @@ describe('merge schemas through transforms', () => {
},
});
});
+
+ it('local subscriptions should work even if root fields are renamed', done => {
+ const originalNotification = {
+ notifications: {
+ text: 'Hello world',
+ },
+ };
+
+ const transformedNotification = {
+ Subscriptions_notifications: originalNotification.notifications
+ };
+
+ const subscription = parse(`
+ subscription Subscription {
+ Subscriptions_notifications {
+ text
+ }
+ }
+ `);
+
+ let notificationCnt = 0;
+ subscribe(mergedSchema, subscription)
+ .then(results => {
+ forAwaitEach(
+ results as AsyncIterable,
+ (result: ExecutionResult) => {
+ expect(result).to.have.property('data');
+ expect(result.data).to.deep.equal(transformedNotification);
+ !notificationCnt++ ? done() : null;
+ },
+ ).catch(done);
+ }).then(() => {
+ subscriptionPubSub.publish(subscriptionPubSubTrigger, originalNotification);
+ }).catch(done);
+ });
});
describe('interface resolver inheritance', () => {