Skip to main content
NestJS CRUD uses a specific query string format to represent complex database queries. Understanding this format helps you build URLs manually or debug issues with the RequestQueryBuilder.

Query String Structure

The query string format follows these conventions:
  • Parameters are separated by &
  • Array values are represented by multiple parameters with the same name
  • The default delimiter for field operators is ||
  • The default delimiter for array values is ,

Available Parameters

fields (select)

Select specific fields to include in the response.
Format: fields=field1,field2,field3
If no fields are specified, all fields are returned by default (unless restricted by the backend).

filter

Apply AND filter conditions. Format: filter=field||operator||value

or

Apply OR filter conditions. Format: or=field||operator||value
OR Conditions

Combining AND and OR

Mixed Conditions
This translates to: (status = 'active') AND (role = 'admin' OR role = 'moderator')

Filter Operators

Equality Operators

Comparison Operators

String Operators

Array Operators

Null Operators

Range Operator

Operators ending with ‘L’ (like $eqL, $contL) perform case-insensitive comparisons. Use these for user-friendly search functionality.

Advanced Search (s)

The s (search) parameter accepts complex nested JSON conditions. Format: s={"field":"value"} (URL encoded)
When the s parameter is present, filter and or parameters are ignored. The search parameter takes precedence.

Search Structure Examples

Simple Field Matching
Field with Operators
OR Conditions
AND Conditions
Complex Nested Logic

Join Relations

Load related entities with their data. Format: join=relation or join=relation||field1,field2
Always specify the fields you need from relations to reduce payload size and improve performance.

Sorting

Sort results by one or more fields. Format: sort=field,ORDER Orders: ASC (ascending) or DESC (descending)

Pagination

Limit

Limit the number of results returned. Format: limit=number
Set Limit
Alternative: per_page=20

Offset

Skip a specific number of records. Format: offset=number
Set Offset
This returns 20 results starting from position 40 (skips first 40).

Page

Use page-based pagination. Format: page=number
Page-based Pagination
This returns page 3 with 20 items per page (items 41-60).
When using page, the offset is calculated as (page - 1) * limit. You should always specify a limit when using page.

Cache Control

Control server-side caching behavior. Format: cache=0 or cache=1
Reset Cache
Setting cache=0 forces a fresh database query, bypassing any cached results.

Soft Deletes

Include soft-deleted records in the results. Format: include_deleted=number
This only works if your entity has soft delete enabled. See the Soft Delete guide for more information.

Complete Examples

Example 1: Basic Filtering and Pagination

Breakdown:
  • Select fields: id, name, email
  • Filter: isActive = true
  • Sort by name ascending
  • Return 20 items from page 1

Example 2: Complex Filtering with Relations

Breakdown:
  • Select post fields: id, title, publishedAt
  • Join author relation (only id and name)
  • Join all comments
  • Filter: status = ‘published’ AND publishedAt >= ‘2024-01-01’
  • Sort by publishedAt descending
  • Limit to 10 results

Example 3: Search with OR Conditions

Breakdown:
  • Select fields: id, name, email
  • Filter: status = ‘active’ AND (role = ‘admin’ OR role = ‘moderator’)
  • Sort by createdAt descending

Example 4: Advanced Search Query

Breakdown (URL decoded):
  • Search: (name contains ‘laptop’ OR description contains ‘laptop’) AND price between 500-2000 AND inStock = true
  • Sort by price ascending

Example 5: Nested Relations

Breakdown:
  • Join posts relation
  • Join comments relation from posts
  • Join author relation from comments (only id and name)
  • Filter posts where status = ‘published’
  • Sort by post publishedAt descending

URL Encoding

When building URLs manually, remember to encode special characters: Example: Unencoded:
Encoded:
The RequestQueryBuilder handles URL encoding automatically when you call .query() or .query(true). Use .query(false) for unencoded strings.

Custom Parameter Names

You can configure custom parameter names on both frontend and backend:
Frontend Configuration
Backend Configuration
With these configurations, your URLs would look like:
Custom Parameter Names

Debugging Query Strings

Browser Console

Network Tab

Inspect the actual request in your browser’s Network tab to see the final URL with all query parameters.

Best Practices

1

Use RequestQueryBuilder

Always use RequestQueryBuilder instead of manually constructing query strings to avoid encoding issues and syntax errors.
2

Select Only Needed Fields

Always specify the fields you need rather than fetching all fields, especially for large entities.
3

Limit Joined Relations

When joining relations, specify which fields to include to reduce payload size.
4

Use Pagination

Always implement pagination for list endpoints to prevent performance issues with large datasets.
5

Index Filtered Fields

Ensure database indexes exist on fields frequently used in filters and sorts for better performance.

Next Steps

RequestQueryBuilder

Learn how to use the RequestQueryBuilder class

Controllers

Set up CRUD controllers to handle these queries