Using QueryBuilder

Query Builder pattern provides a flexible way to construct queries in your domain layer without tightly coupling them to specific query implementations. This tutorial demonstrates how to use a Query Builder class to construct SQL queries, MongoDB pipelines etc. and pass them to a repository method for execution.

Setting up Query Builder

First, let's define a generic Query Builder class that can be extended to build different types of queries:

import { QueryBuilder } from '@soapjs/soap';

/**
 * A class representing a GetUserDetails query builder.
 */
class GetUserDetailsQueryBuilder extends QueryBuilder<string> {
  private parser; // your parser
  build(): string {
    // Constructing SQL query based on arguments
    return parser(`SELECT * FROM table WHERE id = ?`, this.args.id);
  }
}

Using Query Builder

Now, let's see how to use the GetUserDetailsQueryBuilder in a practical scenario. Suppose we have a repository method find that accepts a query built using the Query Builder.

  1. Creating Query Builder Instance:

import { GetUserDetailsQueryBuilder } from '../path/to/get-user-details-query-builder';

// Creating a new instance of GetUserDetailsQueryBuilder
const getUserBuilder = new GetUserDetailsQueryBuilder();
  1. Setting Query Parameters:

We can set the parameters of the query using the with method. It's important to use parameterized queries to prevent SQL injection attacks:

// Setting query parameters using the with() method
getUserBuilder.with({ id: 123 });
  1. Building and Executing the Query:

Once the query parameters are set, we can pass the Query Builder instance to the repository method, where the query will be built and executed safely:

// Executing the query using repository method (inside the repository)
const result = await repository.find(getUserBuilder);

Example Use Case

Let's consider a use case where we want to find a user by their ID from a database. We'll use the Query Builder to construct the SQL query with parameterized values:

import { GetUserDetailsQueryBuilder } from '../path/to/get-user-details-query-builder';

// Creating a new instance of GetUserDetailsQueryBuilder
const getUserBuilder = new GetUserDetailsQueryBuilder();

// Setting query parameters using the with() method
getUserBuilder.with({ id: 123 });

// Executing the query using repository method (inside the repository)
const user = await userRepository.find(getUserBuilder);

Conclusion

Using a Query Builder pattern in the domain layer provides a flexible and decoupled way to construct queries. It allows for easy composition and modification of queries without directly dealing with query implementation details. Please remember, by using parameterized queries, we ensure the security of the application against SQL injection attacks.

Last updated