Skip to content

Commit

Permalink
enable defer stream across schema creation
Browse files Browse the repository at this point in the history
  • Loading branch information
yaacovCR committed Aug 25, 2020
1 parent 3a4084f commit 0a5d362
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,6 @@
"./website"
],
"resolutions": {
"graphql": "15.3.0"
"graphql": "npm:graphql-experimental"
}
}
10 changes: 10 additions & 0 deletions packages/delegate/src/defaultMergedResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ export function defaultMergedResolver(

const data = parent[responseKey];
const unpathedErrors = getUnpathedErrors(parent);

// To Do: extract this section to separate function.
// If proxied result with defer or stream, result may be initially undefined
// so must call out to a to-be-created Receiver abstraction
// (as opposed to Dispatcher within graphql-js) that will notify of data arrival

if (data === undefined) {
return 'test';
}

const subschema = getSubschema(parent, responseKey);

return resolveExternalValue(data, unpathedErrors, subschema, context, info);
Expand Down
51 changes: 51 additions & 0 deletions packages/delegate/tests/deferStream.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { graphql } from 'graphql/experimental';

import { makeExecutableSchema } from '@graphql-tools/schema';

describe('defer support', () => {
test('should work', async () => {
const schema = makeExecutableSchema({
typeDefs: `
type Query {
test(input: String): String
}
`,
resolvers: {
Query: {
test: (_root, args) => args.input,
}
},
});

const result = await graphql(
schema,
`
query {
... on Query @defer {
test(input: "test")
}
}
`,
);

const results = [];
if (result[Symbol.asyncIterator]) {
for await (let patch of result) {
results.push(patch);
}
}

expect(results[0]).toEqual({
data: {},
hasNext: true,
});
expect(results[1]).toEqual({
data: {
test: 'test'
},
hasNext: false,
path: [],
});

});
});
25 changes: 25 additions & 0 deletions packages/load/tests/loaders/schema/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,31 @@ describe('loadSchema', () => {
const schemaStr = printSchema(schema);

expect(schemaStr).toBeSimilarGqlDoc(/* GraphQL */`
"""
Directs the executor to defer this fragment when the \`if\` argument is true or undefined.
"""
directive @defer(
"""Deferred when true or undefined."""
if: Boolean
"""Unique name"""
label: String
) on FRAGMENT_SPREAD | INLINE_FRAGMENT
"""
Directs the executor to stream plural fields when the \`if\` argument is true or undefined.
"""
directive @stream(
"""Stream when true or undefined."""
if: Boolean
"""Unique name"""
label: String
"""Number of items to return immediately"""
initialCount: Int!
) on FIELD
type Query {
a: A
b: B
Expand Down
12 changes: 8 additions & 4 deletions packages/schema/src/buildSchemaFromTypeDefinitions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { extendSchema, buildASTSchema, GraphQLSchema, DocumentNode, ASTNode } from 'graphql';
import { extendSchema, buildASTSchema, GraphQLSchema, DocumentNode, ASTNode, BuildSchemaOptions } from 'graphql';

import { ITypeDefinitions, GraphQLParseOptions, parseGraphQLSDL } from '@graphql-tools/utils';

Expand All @@ -12,12 +12,16 @@ export function buildSchemaFromTypeDefinitions(
const document = buildDocumentFromTypeDefinitions(typeDefinitions, parseOptions);
const typesAst = filterExtensionDefinitions(document);

const backcompatOptions = { commentDescriptions: true };
let schema: GraphQLSchema = buildASTSchema(typesAst, backcompatOptions);
const options: BuildSchemaOptions = {
commentDescriptions: true,
experimentalDefer: true,
experimentalStream: true,
};
let schema: GraphQLSchema = buildASTSchema(typesAst, options);

const extensionsAst = extractExtensionDefinitions(document);
if (extensionsAst.definitions.length > 0) {
schema = extendSchema(schema, extensionsAst, backcompatOptions);
schema = extendSchema(schema, extensionsAst, options);
}

return schema;
Expand Down
8 changes: 8 additions & 0 deletions packages/schema/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,12 @@ export interface IExecutableSchemaDefinition<TContext = any> {
* Additional options for removing unused types from the schema
*/
pruningOptions?: PruneSchemaOptions;
/**
* Set to `true` to enable support within queries for the experimental `defer` directive
*/
experimentalDefer?: boolean;
/**
* Set to `true` to enable support within queries for the experimental `stream` directive
*/
experimentalStream?: boolean;
}
2 changes: 2 additions & 0 deletions packages/stitch/src/stitchSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ export function stitchSchemas({
astNode: schemaDefs.schemaDef,
extensionASTNodes: schemaDefs.schemaExtensions,
extensions: null,
experimentalDefer: true,
experimentalStream: true,
});

extensions.forEach(extension => {
Expand Down
2 changes: 2 additions & 0 deletions packages/stitch/src/stitchingInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ export function addStitchingInfo(stitchedSchema: GraphQLSchema, stitchingInfo: S
...stitchedSchema.extensions,
stitchingInfo,
},
experimentalDefer: true,
experimentalStream: true,
});
}

Expand Down
2 changes: 2 additions & 0 deletions packages/utils/src/addTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,7 @@ export function addTypes(
subscription: subscriptionTypeName != null ? (typeMap[subscriptionTypeName] as GraphQLObjectType) : undefined,
types: Object.keys(typeMap).map(typeName => typeMap[typeName]),
directives,
experimentalDefer: true,
experimentalStream: true,
});
}
2 changes: 2 additions & 0 deletions packages/utils/src/mapSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export function mapSchema(schema: GraphQLSchema, schemaMapper: SchemaMapper = {}
subscription: newSubscriptionTypeName != null ? (typeMap[newSubscriptionTypeName] as GraphQLObjectType) : undefined,
types: Object.keys(typeMap).map(typeName => typeMap[typeName]),
directives,
experimentalDefer: true,
experimentalStream: true,
});
}

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6782,10 +6782,10 @@ graphql-upload@^8.0.2:
http-errors "^1.7.3"
object-path "^0.11.4"

[email protected], graphql@^14.5.3:
version "15.3.0"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.3.0.tgz#3ad2b0caab0d110e3be4a5a9b2aa281e362b5278"
integrity sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w==
[email protected], graphql@^14.5.3, "graphql@npm:graphql-experimental":
version "4.0.1"
resolved "https://registry.yarnpkg.com/graphql-experimental/-/graphql-experimental-4.0.1.tgz#65a2bb1573d20685be62493287c31273419b99ce"
integrity sha512-Z9GHafFdxDMq7sGq+iUdfPCMeTphc/LOOjt2EB9RNDB0j1ShsIg8Bp7PV42oKw3C1ccLvguQaw1DeuldsQuuxw==

gray-matter@^4.0.2:
version "4.0.2"
Expand Down

0 comments on commit 0a5d362

Please sign in to comment.