DEV Community

Cover image for NestJS + class-validator

NestJS + class-validator

Hey folks,

In 14.03.2022 I asked a question1 in class-validator repo about throwing an error when a user sends multiple data while we're gonna allow them to only send one of them.

Recently I've got the time to mix a couple of different approaches to have a better developer experience while following KISS And SOLID. Thus I decided to explain it here for those of you who needs such feature in your NestJS/ExpressJS app (or wherever you're using class-validator).

  1. I created a decorator for the class and called it OneOf.
    • Here we needed to have ValidateIf in order to tell class-validator that it needs to validate a field when that field is present.
    • We are using "logical or" instead of "logical and" because we did not wanna skip the validation on all fields2 listed in the properties completely.
  2. Next, I needed to dynamically add a custom decorator called OneOfChecker to the fields (given by the client3) where we want to ensure only one can be present at a time.
    • Inside that I check whether user had sent all the fields at the same time or not.
    • And inside the defaultMessage I am constructing the error message to have a better readability.

Considerations

This is a real quick fix and not also production ready solution. Because if you read the code closely enough you'll see that we will throw the same error twice for both fields (in our case email and phone). You might think:

  • It is not a big deal and it's user's fault for sending those two fields at the same time.
  • Or you might say that it is really bad and I wanna have it only one. Then you probably need to do something about this part where we are adding OneOfChecker to all passed properties.

If this was helpful to you consider giving it a star on GitHub and a heart to this post on dev.to.

Footnotes


  1. feature: does not allow to send two different parameter at the same time

  2. By fields I meant the key-value pair data sent by the frontend application. Imaging this is what your frontend app sent to your backend: {"email": "a.mail.com", "age": 30}, "email" and "age" here are our fields. 

  3. Client here means where we are using this decorator

Top comments (0)