1.4.1 • Published 9 months ago

@zabih-dev/nest-api-response v1.4.1

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

API Response Wrapper Library for NestJS

This NestJS library provides a standardized API response wrapper that ensures consistent response structures across your application. It includes an interceptor to automatically wrap responses in a DTO format, and also allows flexibility by skipping this behavior using a decorator.

Features

  • Automatic Response Wrapping: Standardizes the API response format with success, status code, message, and error handling.
  • Customizable Responses: Allows returning raw responses by using the @RawResponse() decorator to skipping the wrapped response.
  • Validation Error Handling: Includes a class validator to return errors based on the validation.

Installation

Install the package using npm:

npm install @zabih-dev/nest-api-response

Usage

Open the app.module.ts file and add ApiResponseModule to the imports array.

import { ApiResponseModule } from '@zabih-dev/nest-api-response';
@Module({
  imports: [ApiResponseModule], // Add this line
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Now all routes will return a wrapped response

By default, all API responses will automatically be wrapped in the following format:

export class ApiResponseDto<TData> {
  success: boolean;
  statusCode: number;
  message?: string;
  errors?: ValidationErrorDto[];
  data: TData | TData[];
}

And the ValidationErrorDto is used for handling class validation errors.

export class ValidationErrorDto {
  field: string;
  messages: string[];
}

Example of Wrapped Response

For a successful response:

@Controller()
export class AppController {
  // will be wrapped by the api response
  @Get('users')
  getUsers() {
    return [
      { id: 1, name: 'John' },
      { id: 2, name: 'Petter' },
    ];
  }
}

Wrapped Response:

{
  "success": true,
  "statusCode": 200,
  "message": null,
  "data": [
    {
      "id": 1,
      "name": "John"
    },
    {
      "id": 2,
      "name": "Petter"
    }
  ]
}

Skipping the Response Wrapper

To return a raw response without wrapping it in ApiResponseDto, simply use the @RawResponse() decorator on the handler:

import { RawResponse } from '@zabih-dev/nest-api-response';

@Controller()
export class AppController {
  @RawResponse() // add it to skip the response wrapper
  @Get('users')
  getUsers() {
    return [
      { id: 1, name: 'John' },
      { id: 2, name: 'Petter' },
    ];
  }
}

Response without the wrapping:

[
  {
    "id": 1,
    "name": "John"
  },
  {
    "id": 2,
    "name": "Petter"
  }
]

For a validation error response:

Consider we have a /signin route

// controller.ts
signin(@Body() dto: AuthDto) {
  return dto;
}

// dto.ts file
import { IsEmail, IsNotEmpty, IsString, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';

export class AuthDto {
  @IsEmail()
  @IsNotEmpty()
  email: string;

  @IsString()
  @IsNotEmpty()
  password: string;
}

In case of a validation failure, the response will be structured like this:

{
  "success": false,
  "statusCode": 400,
  "message": "Validation failed",
  "errors": [
    {
      "field": "email",
      "messages": ["email should not be empty", "email must be an email"]
    },
    {
      "field": "password",
      "messages": ["password should not be empty", "password must be a string"]
    }
  ],
  "data": null
}

Support for Nested Errors

The validation error response also supports nested errors when there are objects within objects. For example, if the AuthDto had a nested object like profile:

// dto.ts file
export class ProfileDto {
  @IsString()
  @IsNotEmpty()
  username: string;
}

export class AuthDto {
  @IsEmail()
  @IsNotEmpty()
  email: string;

  @IsString()
  @IsNotEmpty()
  password: string;

  @ValidateNested()
  @Type(() => ProfileDto)
  profile: ProfileDto;
}

If profile contains validation errors, the nested error response will look like this:

{
  "success": false,
  "statusCode": 400,
  "message": "Validation failed",
  "errors": [
    {
      "field": "email",
      "messages": ["email should not be empty", "email must be an email"]
    },
    {
      "field": "password",
      "messages": ["password should not be empty", "password must be a string"]
    },
    {
      "field": "profile",
      "messages": [],
      "errors": [
        {
          "field": "username",
          "messages": ["username should not be empty"]
        }
      ]
    }
  ],
  "data": null
}

This structure allows the response to handle and display validation errors for both top-level and nested fields, making it flexible and clear for complex data validation requirements.

Contributing

Feel free to contribute by submitting a pull request or opening an issue if you find any bugs.

License

MIT License

1.4.1

9 months ago

1.4.0

9 months ago

1.3.0

9 months ago

1.2.0

9 months ago

1.1.0

9 months ago

1.2.2

9 months ago

1.2.1

9 months ago

1.0.0

10 months ago