lucasrochagit / nest-mongo-query-parser

A MongoDB query string parser to be used in applications developed with NestJS.
Apache License 2.0
12 stars 8 forks source link

DTO only fields #16

Closed j-vitali closed 6 months ago

j-vitali commented 6 months ago

HI, very nice library... can I pass only the fileds from my quuery DTO? I don't want user to filter everything...

lucasrochagit commented 6 months ago

Hi @j-vitali, thanks for using this library.

Unfortunately, it is not yet possible to use only fields in your DTO query. But this feature may be available in a future version of the library.

However, you can create a custom decorator to set the other values that you do not want to use to undefined.

j-vitali commented 5 months ago

@lucasrochagit is it a good idea??

import { IsNumber, IsOptional, IsString } from 'class-validator';
import { MongoQueryModel } from 'nest-mongo-query-parser';

export class QueryLanguageDTO extends MongoQueryModel {

  @IsOptional()
  @IsString()
  value: string;
}
lucasrochagit commented 5 months ago

@lucasrochagit is it a good idea??

import { IsNumber, IsOptional, IsString } from 'class-validator';
import { MongoQueryModel } from 'nest-mongo-query-parser';

export class QueryLanguageDTO extends MongoQueryModel {

  @IsOptional()
  @IsString()
  value: string;
}

@j-vitali Currently the library does not support query parameter validations. But this feature may be added in future versions of the library.

j-vitali commented 5 months ago

@lucasrochagit is it a good idea??

import { IsNumber, IsOptional, IsString } from 'class-validator';
import { MongoQueryModel } from 'nest-mongo-query-parser';

export class QueryLanguageDTO extends MongoQueryModel {

  @IsOptional()
  @IsString()
  value: string;
}

@j-vitali Currently the library does not support query parameter validations. But this feature may be added in future versions of the library.

Hi could you give me and example? Maybe another solution will be; create a DTO with all wanted fields, then add pagination also... and then pass it to service that wil be an injectable function and will transform passed DTO to mongoquerymodel. (2nd usage of readme)

What do you think?

lucasrochagit commented 5 months ago

@j-vitali I'm really sorry, I completely forgot about the second usage.

Yes, you can validate some fields from query with the second usage and class validator. You can do something as this example:

the service:

// user.service.ts
import { Injectable } from "@nestjs/common";
import { MongoQueryModel, MongoQueryParser } from "nest-mongo-query-parser";

@Injectable()
export class UserService {
  @MongoQueryParser()
  find(query: MongoQueryModel) {
    return query;
  }
}

the controller:

// user.controller.ts
import { Controller, Get, Query } from "@nestjs/common";
import { UserService } from "./user.service";
import { IsEmail, IsOptional } from "class-validator";
import { MongoQueryModel } from "nest-mongo-query-parser";

class UserQueryModel extends MongoQueryModel {
  @IsOptional()
  @IsEmail()
  email: string;
}

@Controller("user")
export class UserController {
  constructor(private readonly service: UserService) {
  }

  @Get()
  findAll(@Query() query: UserQueryModel) {
    return this.service.find(query);
  }
}

So we have two situations here:

GET /user?email=me@mail.com

Response (ok):

{
   "limit":100,
   "skip":0,
   "select":{},
   "sort":{},
   "populate":[],
   "filter":{
      "email":"me@mail.com"
   }
}

GET /user?email=wrongmail

Response (bad request):

{
   "statusCode":400,
   "message":[
      "email must be an email"
   ],
   "error":"Bad Request"
}

Just be careful about the usage rules, to validate fields properly!

j-vitali commented 5 months ago

very good yes, I used that approach! thank you very much! one more thing, extending MongoQueryModel inside the DTO class is wrong?

import { IsOptional, IsString } from 'class-validator';
import { MongoQueryModel } from '@/common/query-parser' ;

export class SearchDTO extends MongoQueryModel{
  @IsString()
  @IsOptional()
  readonly name: string;

  @IsString()
  @IsOptional()
  readonly industry: string;

  @IsString()
  @IsOptional()
  readonly description: string;    

  @IsString()
  @IsOptional()
  readonly demo: string;  
}
lucasrochagit commented 5 months ago

very good yes, I used that approach! thank you very much! one more thing, extending MongoQueryModel inside the DTO class is wrong?

import { IsOptional, IsString } from 'class-validator';
import { MongoQueryModel } from '@/common/query-parser' ;

export class SearchDTO extends MongoQueryModel{
  @IsString()
  @IsOptional()
  readonly name: string;

  @IsString()
  @IsOptional()
  readonly industry: string;

  @IsString()
  @IsOptional()
  readonly description: string;    

  @IsString()
  @IsOptional()
  readonly demo: string;  
}

I don't think it's wrong, because MongoQueryModel is just a class with a few methods that updates itself fields and only represents the parsed query fields from MongoQueryParser operation.

Just remember put the IsOptional decoration on each SearchDTO. If you forgot to put the decorator in some field, the field becomes required, and it's not a good idea for query fields.

j-vitali commented 5 months ago

thanks a lot, appreciate your effort. for the moment i'll keep as you suggested, then when you will introduce DTO support i will change 💯