toonvanstrijp / nestjs-i18n

The i18n module for nestjs.
https://nestjs-i18n.com
Other
643 stars 108 forks source link

integration with apollo federation #648

Closed javan-b closed 1 month ago

javan-b commented 1 month ago

Describe the bug

Issue Description It appears that nestjs-i18n does not work as expected with Apollo Federation and class-validator in a NestJS application. Specifically, validation errors are not properly translated using nestjs-i18n, and custom exception filters are not being triggered as expected. Despite setting up the necessary i18n configuration and middleware, the translated error messages are not being returned to the client.

Steps to Reproduce Setup a NestJS Application with Apollo Federation and nestjs-i18n:

Install the necessary packages: @nestjs/graphql, @nestjs/apollo, nestjs-i18n, class-validator, and class-transformer. Configure Apollo Federation in the GraphQLModule. Set up the I18nModule with resolvers and translation files. Create a DTO with Validation Decorators:

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail({}, { message: 'validation.INVALID_EMAIL' })
  email: string;

  @IsNotEmpty({ message: 'validation.REQUIRED_FIELD' })
  name: string;
}

Set Up a GraphQL Resolver:

import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { CreateUserDto } from './create-user.dto';

@Resolver()
export class UserResolver {
  @Mutation(() => Boolean)
  async createUser(@Args('input') input: CreateUserDto): Promise<boolean> {
    // Implementation
    return true;
  }
}

Configure I18nModule in AppModule:

import { Module } from '@nestjs/common';
import { I18nModule } from 'nestjs-i18n';
import { GraphQLModule } from '@nestjs/graphql';
import path from 'path';
import { UserResolver } from './user.resolver';

@Module({
  imports: [
    I18nModule.forRoot({
      fallbackLanguage: 'en',
      loaderOptions: {
        path: path.join(__dirname, '/assets/locales'),
        watch: true,
      },
      resolvers: [
        { use: QueryResolver, options: ['lang'] },
        AcceptLanguageResolver,
        new HeaderResolver(['x-lang']),
      ],
    }),
    GraphQLModule.forRoot({
      autoSchemaFile: true,
      context: ({ req }) => ({ req }),
    }),
  ],
  providers: [UserResolver],
})
export class AppModule {}

Custom Validation Pipe with I18nValidationException:

// main.ts

  app.useGlobalPipes(
        new I18nValidationPipe({
            always: true,
            transform: true
        })
    )

   app.useGlobalFilters(
        new I18nValidationExceptionFilter({
            detailedErrors: true,
        })
    )

Expected Behavior Validation errors should be intercepted by the I18nValidationException, and the error messages should be translated using the I18nService. The translated error messages should then be returned to the client.

Actual Behavior The I18nValidationException is not triggered as expected, and the error response contains the original error messages instead of the translated ones. The response typically includes an INTERNAL_SERVER_ERROR code with a generic message.

Observations

The issue may be related to the way Apollo Federation handles errors and validation, which might bypass the custom exception filters. There is no evidence that the I18nValidationException or any custom i18n logic is being applied to the errors.

Example Error Response

{
  "errors": [
    {
      "message": "I18nValidationException: Bad Request",
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "stacktrace": [
          "I18nValidationException: Bad Request",
          "    at I18nValidationPipe.i18nValidationErrorFactory [as exceptionFactory] ..."
        ]
      }
    }
  ]
}

Conclusion

It seems that the current implementation of nestjs-i18n with Apollo Federation does not fully support class-validator error translation and custom exception filters. A detailed investigation is required to determine whether this is a bug or a limitation of the current setup. A potential workaround could involve using a custom error formatter or middleware, but this would require further exploration and may not be the most optimal solution.

the implementation seems to be correct.. where i am able to switch lang with REST API with confidence..

Request for Assistance Assistance is requested in identifying whether this is a bug in the nestjs-i18n library or an issue with the integration with Apollo Federation and class-validator. Any guidance on proper configuration or alternative approaches would be appreciated.

Reproduction

Reproduction for Bug Report: nestjs-i18n with Apollo Federation and class-validator

System Info

System:
    OS: macOS 14.5
    CPU: (8) arm64 Apple M1
    Memory: 72.09 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.12.2 - /usr/local/bin/node
    npm: 10.7.0 - /usr/local/bin/npm
    pnpm: 8.14.3 - /usr/local/bin/pnpm
  Browsers:
    Chrome: 127.0.6533.89
    Safari: 17.5

Used Package Manager

pnpm

Validations

javan-b commented 1 month ago

this is a regular gql issue ... solved with reference to #603

cheers 🥂