profusion / apollo-federation-file-upload

Add file upload support to Apollo Federated services.
32 stars 27 forks source link

nestjs with apollo federation doesn't work #23

Closed flyhigh-hifi closed 3 years ago

flyhigh-hifi commented 3 years ago

Hi! I have tried to combine existing and working data source with file uploads and get errors on both graphql side - (intermediate value).willSendRequest is not a function and on the server – RangeError: Maximum call stack size exceeded

import { Module } from '@nestjs/common';
import { GATEWAY_BUILD_SERVICE, GraphQLGatewayModule } from '@nestjs/graphql';
import { RemoteGraphQLDataSource } from '@apollo/gateway';
import FileUploadDataSource from '@profusion/apollo-federation-upload';

const requestHeadersToForward: Array<string> = [
  'cookie',
  'user-agent',
];

class AuthenticatedDataSource extends FileUploadDataSource {
  async willSendRequest({ request, context }) {
    if (context.req?.headers) {
      super.willSendRequest({ request, context });
      requestHeadersToForward.forEach((h) => {
        if (context.req.headers[h]) {
          request.http.headers.set(h, context.req.headers[h]);
        }
      });
    }
  }

  async didReceiveResponse({ request, response, context }) {
    const cookie = response.http.headers.get('set-cookie');

    if (cookie) {
      context.res.set('set-cookie', cookie);
    }

    return response;
  }
}

@Module({
  providers: [
    {
      provide: AuthenticatedDataSource,
      useValue: AuthenticatedDataSource,
    },
    {
      provide: GATEWAY_BUILD_SERVICE,
      useFactory: (AuthenticatedDataSource) => {
        return ({ name, url }) => new AuthenticatedDataSource({ url });
      },
      inject: [AuthenticatedDataSource],
    },
  ],
  exports: [GATEWAY_BUILD_SERVICE],
})
class BuildServiceModule {}

@Module({
  imports: [
    GraphQLGatewayModule.forRootAsync({
      useFactory: async () => ({
        server: {
          cors: {
            credentials: true,
            allowedHeaders: ['Origin', 'X-Requested-With', 'content-type', 'set-cookie', 'cookie'],
            methods: ['GET, POST, OPTIONS, PUT, PATCH, DELETE'],
            origin: (requestOrigin, cb) => {
              if (!requestOrigin) return cb(null, '*');

              const origins = [/localhost/];
              if (origins.some((o) => o.test(requestOrigin))) {
                return cb(null, true);
              }
              cb(null, false);
            },
          },
          debug: true,
          context: ({ req, res }) => ({ req, res }),
        },
        gateway: {
          debug: true,
          serviceList: [],
        },
      }),
      imports: [BuildServiceModule],
      inject: [GATEWAY_BUILD_SERVICE],
    }),
  ],
})
export class GatewayModule {}
flyhigh-hifi commented 3 years ago

Looks like it's not the issue with nestjs itself, here's a workaround https://github.com/MichalLytek/type-graphql/issues/37#issuecomment-592467594

cabelitos commented 3 years ago

Hi, thank you for the bug report and sorry for the delay.

@flyhigh-hifi Did you manage to find a solution to your problem? The bug does not seem related to this package.

Also we never touch willSendRequest method, so it's highly unlikely that this is a bug on our end. However, if you could provide a reproducible example I could investigate what's happening.

flyhigh-hifi commented 3 years ago

Yes, you are right, this is not related to your package. The solution was to replace internal apollo uploads with graphqlUploadExpress and the problem Maximum call stack in the fs-capacitor package has gone away.

cabelitos commented 3 years ago

closing this since it's resolved

bujosa commented 2 years ago

How I implement this on nestjs?

image