I'm using Angular Universal with Zone.JS and until now thought that it was waiting for my API calls to resolve before delivering the response. As I understand it, Zone.JS patches various libraries in order to know when the application has settled and everything is complete.
Our frontend application is running within AWS Lambda and in a Universal context we make other AWS Lambda Apollo GraphQL calls to our API using a custom link.
If I make API calls using the standard HttpClient from @angular/common/http
then Universal will wait... but when using aws-sdk with https agent then it does not. I can't for the life of me figure out how to patch it with Zone.
When looking at the Angular HttpClient in Server, I can see references to wrapping xhr2 in Zone but am not sure how I'd do the same using https/aws: https://github.com/angular/angular/blob/master/packages/platform-server/src/http.ts#L27
import { Injectable } from '@angular/core';
import { ApolloLink, Observable } from '@apollo/client/core';
import { AuthService } from '@tma/core';
import AwsLambda from 'aws-sdk/clients/lambda';
import { print } from 'graphql';
import { Agent } from 'https';
import { first } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class ApiLinkLambda extends ApolloLink {
client = new AwsLambda({
region: process.env.AWS_REGION,
httpOptions: {
agent: new Agent({
keepAlive: true,
maxSockets: 50,
rejectUnauthorized: true,
}),
},
});
constructor(authService: AuthService) {
super(operation => {
return new Observable(observer => {
authService.token$
.pipe(first())
.toPromise()
.then(token => {
// Make lambda call
return this.client
.invoke({
FunctionName: 'example-graphqlServer',
InvocationType: 'RequestResponse',
Payload: JSON.stringify({
body: {
query: print(operation.query),
variables: operation.variables,
},
headers: {
Authorization: token,
},
httpMethod: 'POST',
path: '/graphql',
requestContext: {
requestTimeEpoch: Date.now(),
},
}),
})
.promise()
.then(result => {
const response = JSON.parse(result.Payload!.toString());
const body = JSON.parse(response.body);
observer.next(body);
observer.complete();
});
});
});
});
}
}