Nest: how to use ValidationPipe with graphql

Created on 27 Jun 2018  路  11Comments  路  Source: nestjs/nest

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

  1. I setup ValidationPipe same as the doc, and use as useGlobalPipes
  2. Also setup graphql
    But do not know how to combine them together, any suggestion?

Expected behavior

Minimal reproduction of the problem with instructions


graphql part:

  @Query()
  async getDates(obj, args, context, info): Promise<string[]> {
    const { code } = args
    return await this.XXXService.find({code})
  }

service part:

  async XXXService(queryDto: QueryDto): Promise<string[]> {
    const { code} = queryDto

    return await getConnection()
      .createQueryBuilder()
      .select.......

What is the motivation / use case for changing the behavior?

Environment


Nest version: X.Y.Z


For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Most helpful comment

I've discovered that using the ValidationPipe with GraphQL works when passing it as an argument for the @Args() decorator:

@Mutation(returns => Group)
async createGroup(
  @Args('group', new ValidationPipe())
  input: CreateGroupInput,
)

All 11 comments

Correct me if I'm not correct.

Dosn't graphQL Validate the payload by default ? I mean, the schema already have types, and graphQL has a Validation layer to make sure that all values matches scheme types!
So why you need the ValidationPipe?

i think he want something like: validate via joi or some rules
e.g
type Bookmark { ... url: String ... }
the schema will check just incoming input type, but some advanced validation like pattern matching or others,

I will suggest to implement it on model layer or on service via DTO

@shekohex Thanks for your reply.
As @aspatari said, I do like use more advanced validation defined in DTO, like MinLength etc in class-validator.

Currently, I copy part of the ValidationPipe logic to graphql xxx.resolvers.ts file, but I feel a bit stupid.

graphql part(xxx.resolvers.ts):

import { validate } from 'class-validator'
import { plainToClass } from 'class-transformer'

  @Query()
  async getDates(obj, args, context, info): Promise<string[]> {
    const { code } = args

/////////////////////////////////added
    const plainObj = { code }
    const class2validate = plainToClass(QueryDto, plainObj)
    const errors = await validate(class2validate, { skipMissingProperties: true })
    if (errors.length > 0) {
      throw new BadRequestException('Validation Failed')
    }
/////////////////////////////////

    return await this.XXXService.find(plainObj)
  }

That is impossible. However, you should take a look at Schema Directives.

@kamilmysliwiec thanks for the link馃榾

Did you manage to get this working @HaveF and perhaps can share example?

@Zeldaze hi, I did not use Schema Directives finally.

Thanks for responding. Did you use another method in that case?

I've discovered that using the ValidationPipe with GraphQL works when passing it as an argument for the @Args() decorator:

@Mutation(returns => Group)
async createGroup(
  @Args('group', new ValidationPipe())
  input: CreateGroupInput,
)

it can also be added at the app level (global pipe) and provided in a module, so Dependency Injection works.
Global Pipes https://docs.nestjs.com/pipes

I dont think it gets called on queries, but it does run for every mutation

@johnnyomair Idea works nice for specific mutations.
Unfortunally in that way, I was unable to make DI work

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FranciZ picture FranciZ  路  3Comments

rlesniak picture rlesniak  路  3Comments

janckerchen picture janckerchen  路  3Comments

artaommahe picture artaommahe  路  3Comments

yanshuf0 picture yanshuf0  路  3Comments