NodeJS

Common approaches for validating input using TypeORM


Common approaches for validating input using TypeORM

Input validation is a fundamental part of building robust applications. As we work with databases and use an ORM like TypeORM in our Node.js applications, we must ensure that the data is valid when being saved. In this blog post, we will walk through common approaches used to validate input in TypeORM, illustrated by examples, code snippets, and full explanations.

Popular Ways of Input Validation in TypeORM

TypeORM itself does not use any built-in input validation. However, it can easily be used together with external validation libraries-the most popular one is class-validator. That library works pretty well with TypeORM entities, allowing you to declare validation rules using decorators.

There are three very common ways to validate input with TypeORM:

Using Class-Validator with TypeORM

Using DTOs (Data Transfer Objects) for Validation in NestJS

1. Class-Validator with TypeORM

class-validator is a pretty strong library that will let you validate JavaScript objects based on decorators. It's very well suited with TypeORM entities.

Install the required dependencies: 

npm install class-validator class-transformerAnnotate your TypeORM entity with validation decorators.

import {Entity, Column, PrimaryGeneratedColumn } from 'typeorm';import { IsString, IsInt, Min, Max, IsEmail } from 'class-validator'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() @IsString({message: 'First name must be a string' }) firstName: string; @Column() @IsString({ message: 'Last name must be a string' }) lastName: string; @Column() @IsEmail({}, {message: Invalid email format' }) email: string; @Column() @IsInt() @Min (18, message: 'Age must be at least 18' }) @Max (99, message: 'Age must be less than 99')) age: number;

In the following example, we will utilize decorators such as @IsString() and @IsEmail(), to define our validation rules. The rules above ensure the firstName, email, and age data all satisfy some constraints before getting saved into the database.

2. Using DTO in NestJS Application to Validate

NestJS provides a much cleaner approach to input validation using Data Transfer Objects (DTOs) in tandem with class-validator. All the validating logic is kept outside of entities, focused more on validating data which is being sent to APIs.

import { IsString, IsInt, Min, Max, IsEmail } from 'class-validator'; export class CreateUserDto { @IsString() firstName: string; @IsString() lastName: string; @IsEmail() email: string; @IsInt() @Min (18) @Max (99) age: number;import { Body, Controller, Post } from '@nestjs/common'; import { CreateUserDto } from './create-user.dto'; import { UserService } from './user.service'; @Controller('users') export class UserController { constructor (private readonly userService: UserService) {} Tabnine | Edit | Test | Explain | Document | Ask @Post() async createUser(@Body() createUserDto: CreateUserDto) { return this.userService.createUser(createUserDto); async createUser (createUserDto: CreateUserDto) { const user = new User(); Object.assign(user, createUserDto); return await this.userRepository.save(user);

This way, you decouple the validation rules from the entity, which makes your code much more flexible and reusable.

Additional Validation Techniques

1. Database-Level Validation:

You can also enforce validation at the database level using column constraints. For example,

@Column ({unique:true})email: string;@Column ({unique:true})firstName: string;

But solely depending on database constraints might yield a less informative error message with a slower error detection rate as opposed to application-level validation.

2. Pipes in NestJS

And if you use NestJS, the built-in validation pipes of the framework automatically validate incoming requests with the help of DTOs that you need to define in your controller, so you will avoid some extra code.

import { ValidationPipe} from '@nestjs';app.useGlobalPipes(new ValidationPipe())

Conclusion

Validating input is one of the basic parts of any application dealing with a database. With TypeORM combined with a class-validator or using DTOs in NestJS, you can easily make your validation logic scalable and maintainable. Such approaches ensure that only valid data gets into your database- and at the same time, always avoids bugs, corrupt data, and security vulnerabilities from arising in the future.

The approach should be chosen concerning the architecture for the application. For less complex validations, the mere use of decorators directly on your entity would be enough, but for much more complex applications, using DTOs with validation pipes in something like NestJS gives a cleaner and more scalable solution.

Ready to transform your business with our technology solutions? Contact us today to Leverage Our NodeJS Expertise.

NodeJS

Related Center Of Excellence