Skip to content

Fix/enable case insensitive queries #15127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

Ozair007
Copy link

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

What is the current behavior?

In NestJS v11, after the upgrade to Express 5.x, the req.query property became a read-only getter. This broke any middleware or logic that attempted to modify req.query to normalize query parameter keys (e.g., to make them case-insensitive). Currently, there is no built-in way to enable case-insensitive query handling in the @nestjs/platform-express package, and attempting to modify req.query directly results in a TypeError: Cannot set property query of # which has only a getter

Issue Number: #15115

What is the new behavior?

This PR introduces a new method enableCaseInsensitiveQueries to the ExpressAdapter class in the @nestjs/platform-express package. The method adds a middleware that normalizes all query parameter keys to lowercase, ensuring case-insensitive handling of query parameters. Key features of the new behavior include:

  • Query parameter keys are normalized to lowercase (e.g., NAME=John becomes accessible as name).
  • Supports nested objects and arrays in query parameters (e.g., DETAILS[address]=123+St becomes details[address]).
  • The middleware uses Object.defineProperty to override the req.query getter, ensuring compatibility with Express 5.x’s read-only req.query.
  • Comprehensive tests cover edge cases such as arrays, nested objects, and empty queries.
  • The feature can be enabled by calling app.enableCaseInsensitiveQueries() after creating the Nest application.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

  • Documentation Proposal: Below is a proposed documentation addition for maintainers to review and include:

Case-Insensitive Query Parameters

Starting with NestJS v11, you can enable case-insensitive query parameter handling in applications using the @nestjs/platform-express package. This feature normalizes all query parameter keys to lowercase, allowing controllers to access parameters consistently regardless of the case used in the request URL.

To enable this feature, call the enableCaseInsensitiveQueries method on your application instance:

import { NestFactory } from '@nestjs/core';
import { ExpressAdapter, NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
    new ExpressAdapter(),
  );
  app.enableCaseInsensitiveQueries();
  await app.listen(3000);
}
bootstrap();

Example

With case-insensitive queries enabled, a request to /test?NAME=John&AGE=30 will be processed as if the parameters were name=John and age=30. A controller can then access these parameters without worrying about the case:

import { Controller, Get, Query, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('test')
export class AppController {
  @Get()
  getQuery(@Req() req: Request) {
    const normalizedQuery = req.query;
    const response = Object.entries(normalizedQuery)
      .map(([key, value]) => {
        const displayValue = Array.isArray(value)
          ? value.join(', ')
          : (value?.toString() ?? 'undefined');
        return `${key}: ${displayValue}`;
      })
      .join(', ');
    return response || 'No query parameters provided';
  }
}

This feature also supports nested objects and arrays in query parameters, ensuring consistent normalization across all keys.

  • Performance Consideration: The Object.defineProperty approach is applied per request, which might have a minor performance overhead for applications with high query parameter usage. Future optimizations could include caching the normalized query object if needed.
  • Future Improvement: The middleware currently relies on Object.defineProperty to override req.query. A more extensible approach might involve exposing a public API for custom query parameter transformations, which could be proposed in a follow-up PR if maintainers are interested.

This PR closes issue #15115 by addressing the Express 5.x compatibility issue and providing a new feature for case-insensitive query handling.

Ozair007 added 2 commits May 13, 2025 15:08
- Introduce enableCaseInsensitiveQueries method to normalize query
  parameters to lowercase.
- Handle nested objects and arrays for robust normalization.
- Update tests to cover edge cases.

Closes nestjs#15115
- Add tests for arrays, nested objects, and empty queries.

Closes nestjs#15115
@kamilmysliwiec
Copy link
Member

kamilmysliwiec commented May 14, 2025

Thanks for your contribution.
However, please see this #15115 (comment) for more info.

If you'd like the Express team to make the query attribute writable again, please create a new issue in their repository. We shouldn't interfere with the underlying HTTP driver's behavior

@nestjs nestjs locked and limited conversation to collaborators May 14, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants