1

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();
              });
          });
      });
    });
  }
}
creamcheese
  • 2,524
  • 3
  • 29
  • 55

0 Answers0