Danh mụcThẻBài viết

admin

I'm a Full-stack developer

Thẻ

Linked List
Data Structure
Chat GPT
Design Pattern
Microservices
API
AWS CDK
ReactJS
AWS Lightsail
Flutter Mobile
TypeScript Design Pattern - Builder
Ngày đăng: 07/08/2023

What is a builder pattern?

The builder pattern is one of the Creational pattern groups. The responsibility is to build a complex object with basic objects step by step.


When should I use the builder pattern?

The builder pattern should be used when a developer wants to:


  • Having a lot of constructors.
  • Control the build process.
  • Decouple the build complex object process from the component of an object.
  • Initialize an object that has greater than 4 properties including required and optional properties.


How to implement

For example, we will create an object to validate API schema including body, param, and query.


base.validation.ts
export class BaseValidation {
  protected readonly _httpRequest: { params?: any; query?: any; body?: any };

  constructor() {
    this._httpRequest = {};
  }

  findOneBuilder() {
    return this;
  }

  deleteOneBuilder() {
    this._httpRequest.params = Joi.object().keys({
      id: Joi.string().custom(objectId),
    });


    return this;
  }

  updateOneBuilder() {
    this._httpRequest.params = Joi.object().keys({
      id: Joi.string().custom(objectId),
    });


    return this;
  }

  insertOneBuilder() {
    return this;
  }

  searchBuilder() {
    this._httpRequest.query = {};


    return this;
  }

  withBody(body) {
    this._httpRequest.body = body;


    return this;
  }

  withFilter(filter) {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      ...filter,
      isAll: Joi.string(),
      includeId: Joi.string(),
    };

    return this;
  }

  withPopulate() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      populate: Joi.string(),
    };

    return this;
  }

  withSelect(select) {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      select: select,
    };

    return this;
  }

  withSortBy() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      sort_fields: Joi.string(),
      sort: Joi.string(),
    };

    return this;
  }

  withLimit() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      limit: Joi.number().integer(),
    };

    return this;
  }

  withPage() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      page: Joi.number().integer(),
    };

    return this;
  }

  build() {
    return {
      ...(this._httpRequest.body && { body: this._httpRequest.body }),
      ...(this._httpRequest.query && { query: this._httpRequest.query }),
      ...(this._httpRequest.params && { query: this._httpRequest.params }),
    };
  }
}


tag.validation.ts
export class TagValidation extends BaseValidation {
  constructor() {
    super();
  }

  searchBuilder() {
    return super
      .searchBuilder()
      .withSelect(Joi.custom(this.select))
      .withPage()
      .withPopulate()
      .withLimit()
      .withSortBy()
      .withFilter({
        name: Joi.string(),
      })
      .build();
  }

  private select(value: string, helpers: CustomHelpers) {
    const selectFields = ['name', 'description', 'slug'];

    if (value) {
      const valueList = value.split(',');
      const difference = valueList.filter((x) => !selectFields.includes(x));

      if (difference.length > 0) {
        return helpers.message({ custom: `"{{#label}}" must be in ${selectFields}` });
      }
    }

    return value;
  }
}


tag.route.ts
validateSchemaMiddleware(new TagValidation().searchBuilder());


Execution result

/tags?limit=1&select=name
{
    "statusCode": "10000",
    "status": 200,
    "message": "",
    "data": {
        "record": [
            {
                "id": 6,
                "name": "React JS"
            }
        ],
        "limit": 1,
        "total": 6,
        "page": 1
    }
}


/tags?limit=1&select=title
{
    "statusCode": "10001",
    "status": 400,
    "message": "Invalid request",
    "data": {
        "query": [
            "\"\"select\"\" must be in name,description,slug"
        ]
    }
}


Pros and Cons

Pros:


  • Support, and eliminate the need to write many constructors.
  • The code is easier to read and easier to maintain when the number of properties is required to create an object from 4 or 5 properties.
  • Reduce the number of constructors, no need to pass null values for unused parameters.
  • Safer Constructed Objects.
  • Gives you better control over the build process.
  • It is possible to create immutable objects.

Cons:


  • Duplicate code.
  • Rase code complexity.


Wrapping Up

Thank you for reading, and happy coding!

I hope this article will help make the concepts of the Builder Pattern

Đề xuất

Create S3 Bucket with AWS CDK
admin09/06/2023

Create S3 Bucket with AWS CDK
In this article, I introduce Amazon CDK and how to write AWS infrastructure-as-code using TypeScript. We will do it step by step.
Form validator in Flutter with EzValidator
admin04/01/2024

Form validator in Flutter with EzValidator
When I am working on Flutter with form. For ensuring data integrity, and handling user input errors. I want to show an error message below each TextField, Dropdown, Switch, ... if the user does not input or wrong input. The EzValidator help me to resolve this.
TypeScript Design Pattern - Bridge
admin08/08/2023

TypeScript Design Pattern - Bridge
Decouple an abstraction from its implementation so that the two can vary independently.
Mới nhất

TypeScript Design Pattern - Builder
admin07/08/2023

TypeScript Design Pattern - Builder
TypeScript Design Pattern - Builder
NodeJS Verify and Decode Cognito JWT Tokens
admin12/06/2023

NodeJS Verify and Decode Cognito JWT Tokens
In this article, I will show you how to verify and decode the Cognito JWT Tokens token.
How to secure your API gateway
admin17/04/2024

How to secure your API gateway
In this blog, I will cover the 6 methods that technology leaders need to incorporate to secure and protect APIs.
Đinh Thành Công Blog

My website, where I write blogs on a variety of topics and where I have some experiments with new technologies.

hotlinelinkedinskypezalofacebook
DMCA.com Protection Status
Góp ý
Họ & Tên
Số điện thoại
Email
Nội dung
Tải ứng dụng
hotline

copyright © 2023 - AGAPIFA

Privacy
Term
About