-
-
Notifications
You must be signed in to change notification settings - Fork 229
Expand file tree
/
Copy pathGraphileApolloLink.ts
More file actions
91 lines (86 loc) · 2.41 KB
/
GraphileApolloLink.ts
File metadata and controls
91 lines (86 loc) · 2.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import {
ApolloLink,
FetchResult,
NextLink,
Observable,
Operation,
} from "@apollo/client";
import { Request, Response } from "express";
import { execute, hookArgs, isAsyncIterable } from "grafast";
import type {} from "postgraphile/grafserv/express/v4";
import { getOperationAST } from "graphql";
import type { PostGraphileInstance } from "postgraphile";
export interface GraphileApolloLinkInterface {
/** The request object. */
req: Request;
/** The response object. */
res: Response;
/** The instance of the express middleware returned by calling `postgraphile()` */
pgl: PostGraphileInstance;
}
/**
* A Graphile Apollo link for use during SSR. Allows Apollo Client to resolve
* server-side requests without requiring an HTTP roundtrip.
*/
export class GraphileApolloLink extends ApolloLink {
constructor(private options: GraphileApolloLinkInterface) {
super();
}
request(
operation: Operation,
_forward?: NextLink
): Observable<FetchResult> | null {
const { pgl, req, res } = this.options;
return new Observable((observer) => {
(async () => {
try {
const {
operationName,
variables: variableValues,
query: document,
} = operation;
const op = getOperationAST(document, operationName);
if (!op || op.operation !== "query") {
if (!observer.closed) {
/* Only do queries (not subscriptions) on server side */
observer.complete();
}
return;
}
const schema = await pgl.getSchema();
const args = {
schema,
document,
variableValues,
operationName,
};
await hookArgs(args, pgl.getResolvedPreset(), {
node: {
req,
res,
},
expressv4: {
req,
res,
},
});
const data = await execute(args);
if (isAsyncIterable(data)) {
data.return?.();
throw new Error("Iterable not supported by GraphileApolloLink");
}
if (!observer.closed) {
observer.next(data);
observer.complete();
}
} catch (e: any) {
if (!observer.closed) {
observer.error(e);
} else {
console.error(e);
}
}
})();
});
}
}