Skip to content

[Feature Request]: HttpResponse class for better return status ✨ #15244

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

Open
1 task done
Avivbens opened this issue Jun 6, 2025 · 0 comments
Open
1 task done

[Feature Request]: HttpResponse class for better return status ✨ #15244

Avivbens opened this issue Jun 6, 2025 · 0 comments
Labels
needs triage This issue has not been looked into type: enhancement 🐺

Comments

@Avivbens
Copy link

Avivbens commented Jun 6, 2025

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

The Issue

Very often in development, we'd like to return a different status code rather than the obvious ones:

GET / PUT / DELETE / PATCH => 200
POST => 201

For instance, we can return 204 - No Content when there are no results for the query, or 304 - Not Modified to reduce traffic when there are no changes.

The Current Usage

Nest allows us to directly use the Response instance, by default from express:

import { Controller, Get, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Res({ passthrough: true }) res: Response) {
     res.status(HttpStatus.NO_CONTENT)
     return []
  }
}

Based on the official Nest.js documentation, this approach needs to be handled very elegantly, as by default it disables the standard way that Nest handles endpoints.

Official Docs

Nest detects when the handler is using either @Res() or @Next(), indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is automatically disabled for this single route and will no longer work as expected. To use both approaches at the same time (for example, by injecting the response object to only set cookies/headers but still leave the rest to the framework), you must set the passthrough option to true in the @Res({ passthrough: true }) decorator.

Proposal - Return HttpResponse

Exists API for Exceptions

Just like throwing errors with HttpException instance, for example the ForbiddenException class:

import { Controller, Post, Body, ForbiddenException } from '@nestjs/common';

@Controller('auth')
export class AuthController {

  @Post('login')
  login(@Body() { username, password }: any) {
    if (password !== '1234') {
      throw new ForbiddenException('Invalid credentials'); // Existing API
    }

    return { token: 'jwt.token.here' };
  }
}

New API

import {
  Controller,
  Get,
  Post,
  Version,
  HttpStatus,
} from '@nestjs/common';
import {
  HttpResponse,
  NoContentResponse,
  PartialContentResponse,
  OkResponse,
  CreatedResponse,
  AcceptedResponse,
} from './http-response'; // hypothetical new API

@Controller('items')
export class ItemsController {

  /**
   * v1 — Return plain object (default Nest behavior)
   */
  @Get()
  async getItemsV1() {
    const items = [];

    if (!items.length) {
      return new NoContentResponse(); // ✅ Predefined semantic response
    }

    return { items }; // ✅ Fully supported — raw object
  }

  /**
   * v2 — Return `204` when no results
   */
  @Version('2')
  @Get()
  async getItemsV2() {
    const items = [];

    if (!items.length) {
      return new NoContentResponse(); // ✅ Predefined semantic response
    }

    return new OkResponse({ items }); // Optional, clearer intent
  }

  /**
   * v3 — Return `206` Partial Content + headers
   */
  @Version('3')
  @Get()
  async getItemsV3() {
    const items = ['limited', 'page'];

    return new PartialContentResponse({ items }, {
      headers: { 'X-Page-Limit': 'true' },
    });
  }

  /**
   * v4 — Dynamic custom response: status, headers
   */
  @Version('4')
  @Get()
  async getItemsV4() {
    const items = ['item1', 'item2'];

    return new HttpResponse({ items }, {
      status: HttpStatus.PARTIAL_CONTENT,
      headers: {
        'X-Custom': 'value',
        'X-Trace-Id': 'abc-xyz',
      },
    });
  }

  /**
   * v5 — POST endpoint returning `201` Created
   */
  @Version('5')
  @Post()
  async createItem() {
    const created = { id: 'new-id', name: 'apple' };

    return new CreatedResponse(created);
  }

  /**
   * v6 — Async operation acknowledged with `202` Accepted
   */
  @Version('6')
  @Post('async-task')
  async createAsyncTask() {
    return new AcceptedResponse({ message: 'Task accepted for processing' });
  }
}

It would be nice to have the same capabilities for a non-error response, so we can control the status code with a specific class dynamically, and potentially more custom options that are not currently provided with the robust all-included controller engine of Nest.js.

The Solution

Just like HttpException is handled by the default Exceptions Handler, we could introduce a new Interceptor that developers could register globally, per controller, or per route.
This Interceptor will check if the return type is an instance of the new classes and change the behavior accordingly.

Side Note

I'm open to ideas about what else we can add here, not just the status. Technically, with the right API, it could be customizable at any level, allowing the end user to define whatever they want with 1-2 lines of code, potentially removing the need to directly touch the response object 80% of the time!

I'll be more than happy to be involved in this development if the community finds it interesting enough 🥷

I guess developers like me would find it beneficial as well 🙏

@Avivbens Avivbens added type: enhancement 🐺 needs triage This issue has not been looked into labels Jun 6, 2025
@Avivbens Avivbens changed the title [Feature Request]: HttpResponse class for better return status [Feature Request]: HttpResponse class for better return status & options Jun 6, 2025
@Avivbens Avivbens changed the title [Feature Request]: HttpResponse class for better return status & options [Feature Request]: HttpResponse class for better return status ✨ Jun 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage This issue has not been looked into type: enhancement 🐺
Projects
None yet
Development

No branches or pull requests

1 participant