1
- import { printSchema , print , ExecutionResult , Kind , ValueNode } from 'graphql' ;
1
+ import { printSchema , print , Kind , ValueNode , ExecutionResult } from 'graphql' ;
2
+ import { execute , makePromise , ApolloLink , Observable } from 'apollo-link' ;
3
+
2
4
import {
3
5
GraphQLFieldResolver ,
4
6
GraphQLSchema ,
@@ -25,25 +27,51 @@ export type Fetcher = (
25
27
} ,
26
28
) => Promise < ExecutionResult > ;
27
29
30
+ export const fetcherToLink = ( fetcher : Fetcher ) : ApolloLink => {
31
+ return new ApolloLink ( operation => {
32
+ return new Observable ( observer => {
33
+ const { query, operationName, variables } = operation ;
34
+ const context = operation . getContext ( ) ;
35
+ fetcher ( {
36
+ query : typeof query === 'string' ? query : print ( query ) ,
37
+ operationName,
38
+ variables,
39
+ context,
40
+ } )
41
+ . then ( ( result : ExecutionResult ) => {
42
+ observer . next ( result ) ;
43
+ observer . complete ( ) ;
44
+ } )
45
+ . catch ( observer . error . bind ( observer ) ) ;
46
+ } ) ;
47
+ } ) ;
48
+ } ;
49
+
28
50
export default function makeRemoteExecutableSchema ( {
29
51
schema,
52
+ link,
30
53
fetcher,
31
54
} : {
32
55
schema : GraphQLSchema ;
33
- fetcher : Fetcher ;
56
+ link ?: ApolloLink ;
57
+ fetcher ?: Fetcher ;
34
58
} ) : GraphQLSchema {
59
+ if ( fetcher && ! link ) {
60
+ link = fetcherToLink ( fetcher ) ;
61
+ }
62
+
35
63
const queryType = schema . getQueryType ( ) ;
36
64
const queries = queryType . getFields ( ) ;
37
65
const queryResolvers : IResolverObject = { } ;
38
66
Object . keys ( queries ) . forEach ( key => {
39
- queryResolvers [ key ] = createResolver ( fetcher ) ;
67
+ queryResolvers [ key ] = createResolver ( link ) ;
40
68
} ) ;
41
69
let mutationResolvers : IResolverObject = { } ;
42
70
const mutationType = schema . getMutationType ( ) ;
43
71
if ( mutationType ) {
44
72
const mutations = mutationType . getFields ( ) ;
45
73
Object . keys ( mutations ) . forEach ( key => {
46
- mutationResolvers [ key ] = createResolver ( fetcher ) ;
74
+ mutationResolvers [ key ] = createResolver ( link ) ;
47
75
} ) ;
48
76
}
49
77
@@ -88,18 +116,22 @@ export default function makeRemoteExecutableSchema({
88
116
} ) ;
89
117
}
90
118
91
- function createResolver ( fetcher : Fetcher ) : GraphQLFieldResolver < any , any > {
119
+ function createResolver ( link : ApolloLink ) : GraphQLFieldResolver < any , any > {
92
120
return async ( root , args , context , info ) => {
93
- const operation = print ( info . operation ) ;
94
- const fragments = Object . keys ( info . fragments )
95
- . map ( fragment => print ( info . fragments [ fragment ] ) )
96
- . join ( '\n' ) ;
97
- const query = `${ operation } \n${ fragments } ` ;
98
- const result = await fetcher ( {
99
- query,
100
- variables : info . variableValues ,
101
- context,
102
- } ) ;
121
+ const fragments = Object . keys ( info . fragments ) . map (
122
+ fragment => info . fragments [ fragment ] ,
123
+ ) ;
124
+ const document = {
125
+ kind : Kind . DOCUMENT ,
126
+ definitions : [ info . operation , ...fragments ] ,
127
+ } ;
128
+ const result = await makePromise (
129
+ execute ( link , {
130
+ query : document ,
131
+ variables : info . variableValues ,
132
+ context,
133
+ } ) ,
134
+ ) ;
103
135
const fieldName = info . fieldNodes [ 0 ] . alias
104
136
? info . fieldNodes [ 0 ] . alias . value
105
137
: info . fieldName ;
0 commit comments