12

A NestJS project uses a ValidationPipe with class-validator to validate POST requests. It would be nice to use the same class-validator DTO in the (react) front-end .

How could the entities in the DTO be linked to react elements ?

This may be similar to How to Sync Front end and back end validation, but more focused on specific tools.

3
  • 1
    If you want to bind validation rules to your form elements like input then you can try something like react-class-validator which is not depending on any form libraries. Commented Feb 10, 2021 at 9:20
  • Thanks, @VladGoldman , I had ruled out the react-class-validator, as it had seen very little use. Prematurely seemingly . Any example how that would work ? Commented Feb 11, 2021 at 16:20
  • @serv-inc did you check github.com/anigenero/react-class-validator or similar libraries? Commented Feb 12, 2021 at 9:34

2 Answers 2

7

We had exactly the same need a couple of months ago with a NestJS backend and Angular frontend. What we've done is to create a third project called "API-Common" using NestJS where we've gathered all the common DTOs and utilities that are needed in both the backend and frontend. To share it, we create an NPM package from the project so we can import it in both applications.

You can learn more about creating your private NPM registry in the following link:

https://gemfury.com/help/npm-registry/

Sign up to request clarification or add additional context in comments.

3 Comments

Why didn't you go for a mono repo?
Hi! We used this solution because we intended to use the NPM package in several applications that don't relate to each other so we wanted to be as modular as possible. With NPM 7, we're using its workspaces feature to define monorepos for our latest projects, it's really convenient.
Absolutely brilliant, I am using this exact same structure with npm
2

Well Nestjs itself uses class-validators for DTOs,

So you can move them to an external package, there you'll be able to declare your DTOs.

After doing that you can consume the DTOs from your NestJS app and also from your React app.

For example, this is my implementation of a DTO on a package:

    
    export const getCreateUserDto = (ApiPropertySwagger?: any) => {
      // We did this to avoid having to include all nest dependencies related to ApiProperty on the client side too
      // With this approach the value of this decorator will be injected by the server but wont affect the client
      const ApiProperty = ApiPropertySwagger || function () {};
    
      class CreateUserDto {
        @IsEmail()
        @ApiProperty({
          description: "This is required and must be a valid email",
          type: String,
        })
        email: string;
    
        @IsString()
        @MinLength(2)
        @ApiProperty({
          description: "This is required and must be at least 2 characters long",
          type: String,
        })
        firstName: string;
    
        @IsString()
        @IsOptional()
        lastName?: string;
    
        @IsString()
        @IsOptional()
        nationality?: string;
      }
    
      return CreateUserDto;
    };

In your NestJS app you can do the following:

import { ApiProperty } from '@nestjs/swagger';
// Here we send `ApiProperty` dependency to  be added to`CreateUserDto`
export const _CreateUserDto = getCreateUserDto(ApiProperty);

// This allows using it as a TS type and as a constructor class
export class CreateUserDto extends _CreateUserDto {} 

And in your react app you can do:

import { getCreateUserDto } from "@sample/dtos";    
    // We don't need `ApiProperty` on the client,
    // so it will fallback on the default empty decorator 
    const _CreateUserDto = getCreateUserDto();
    // This allows using it as a TS type and as a constructor class
    class CreateUserDto extends _CreateUserDto {}

I just posted a blog with this implementation:

https://dev.to/facup3/fullstack-nestjs-dtos-for-your-web-app-4f60

I used React + react-hook-form to run same validations on the client side than in the nest controllers.

2 Comments

Thanks for the answer. +1 If you post an extract here (or just as well the whole blog post), you might get more upvotes.
My apologies, I'm new answering 🤣

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.