4lessandrodev / rich-domain

A lib to help you create a robust project based on domain driven-design (ddd) principles with typescript and zero dependencies.
https://www.npmjs.com/package/rich-domain
MIT License
122 stars 5 forks source link

Question: have you considered using `class-validator` for validation? #22

Closed leonardbinet closed 1 year ago

leonardbinet commented 1 year ago

Is your feature request related to a problem? Please describe.

First, congratulation @4lessandrodev for this great lib 🏅, I really appreciate your work!

In your lib, you declare a Validator class, I think that validation is a topic that is well addressed by some dedicated packages, notably class-validator which provide rich functionalities.

Wouldn't it make sense to rather use such lib rather than writing a custom implementation?

I see those potential benefits:

Describe the solution you'd like

In your example app, let's take the example of the product-price value object:

import { IResult, Result, ValueObject } from "types-ddd";

export interface PriceProps {
    value: number;
}

export class ProductPrice extends ValueObject<PriceProps>{
    private constructor(props: PriceProps) {
        super(props);
    }

    validation(value: number): boolean {
        return ProductPrice.isValidProps({ value });
    }

    public static isValidProps({ value }: PriceProps): boolean {
        const { number } = this.validator;
        return number(value).isPositive();
    }

    public static create(props: PriceProps): IResult<ProductPrice> {
        const message = 'value must be positive';

        if (!this.isValidProps(props)) return Result.fail(message);

        return Result.Ok(new ProductPrice(props));
    }
}

export default ProductPrice;

With some changes on the ValueObject class (adopting such approach ), this might be simplified to:

import { IsNumber, Min } from "class-validator";

import { ValueObject } from "types-ddd";

export class PriceProps {
  @IsNumber()
  @Min(0)
  value: number;
}

export class ProductPrice extends ValueObject<PriceProps> {}

export default ProductPrice;
4lessandrodev commented 1 year ago

Hi @leonardbinet , thanks for the feedback :bulb:!!!

I thought of something similar on this issue But I didn't continue.

About validation, this core library is premised on being free of third-party libraries, But I believe that "decorators" can be a good solution for new implementations.

Just need to find a way to avoid breaking the domain with "throw errors" and returning a result instance.

Feel free to fork and test new implementations and suggestions.

Every help is welcome

Thanks!