Strapi Fluent Query Builder is a powerful library designed to simplify building dynamic queries for Strapi, a popular open-source headless CMS. The library provides a fluent API for constructing complex queries, including filtering, sorting, pagination, relation population, and more.
While intended to be fully compatible with Strapi's REST API, this library is agnostic to Strapi and can be used with any RESTful API that follows similar conventions.
- Fluent API: Build queries using a clean, chainable API.
- Filters: Support for multiple filter types (equality, inclusion,
contains
, logical operators like$and
,$or
,$not
, and more). - Sorting: Sort by one or more fields, with both ascending and descending order.
- Pagination: Control pagination with options for page size, starting index, page number, and total count.
- Relation Population: Populate relations and nested relations with the ability to filter and select specific fields from related resources.
- Content Status: Easily filter content based on status (
published
,draft
). - Localization: Query content in different locales.
- Field Selection: Select specific fields to reduce payload size and improve performance.
- Type Safety: Built with TypeScript, ensuring full type safety across all query operations.
To install the library, use npm or yarn:
npm install @codechem/strapi-fluent-rest-api
Or with yarn:
yarn add @codechem/strapi-fluent-rest-api
Create a query builder instance using the query
function, then chain methods to customize your query:
import { query } from '@codechem/strapi-fluent-rest-api';
const result = query('books')
.where('title.$contains', 'example')
.sort('createdAt', 'desc')
.page(1)
.pageSize(10)
.get();
console.log(result);
You can apply filters using the where
or filter
methods. The where
method allows you to specify a field and its value, while the filter
method accepts a bulk filter object.
// Using where method
const result = query('templates')
.where('title.$eq', 'test')
.where('status.$eq', 'published')
.get();
// Using filter method
const result = query('templates').filter({
title: { $eq: 'test' },
status: { $eq: 'published' },
tags: { $in: [1, 2, 3] },
}).get();
You can also use logical operators such as $and
, $or
, and $not
to combine multiple filters.
// Using logical operators
const result = query('templates')
.and(
{ title: { $eq: 'test' } },
{ status: { $eq: 'published' } }
)
.or({ tags: { $in: [1, 2, 3] } })
.get();
Sort the query results by one or more fields using the sort
method. You can specify the sort direction (asc
or desc
):
const result = query('templates')
.sort('createdAt', 'desc')
.sort('title', 'asc')
.get();
Control pagination by using page
, pageSize
, limit
, and start
methods. You can also request the total count of results by using the withCount
method:
const result = query('templates')
.page(1)
.pageSize(10)
.start(0)
.limit(10)
.withCount(true)
.get();
You can populate related resources using the populate
method. To populate nested relations or apply filters to related resources, use populateQ
:
// Populate a single relation
const result = query('books').populate('user');
// Populate multiple relations
const result = query('books').populate('user', 'readers.books');
// Populate relations with filters
const result = query('books').populateQ('user', user => user.where('name.$eq', 'John Doe'));
// Populate nested relations with filters
const result = query('books').populateQ(
query('user')
.where('name.$eq', 'John Doe')
.populateQ('friends', friend => friend..where('name.$eq', 'Jane Doe'))
);
You can filter content based on its status (published or draft) using the status
, drafts
, and published
methods:
const result = query('templates').published(); // Status: published
const result = query('templates').drafts(); // Status: draft
Additionally, set the locale of the content with the locale
method:
const result = query('templates').locale('mk');
Reduce the response size by selecting only the fields you need with the fields
or select
method:
const result = query('templates').fields('id', 'title', 'description');
You can generate the full query string using the qs
method, or generate the full URL with the full
method, which includes the resource name and query string:
const queryString = query('templates')
.where('title.$eq', 'test')
.qs();
console.log(queryString); // Generated query string
const fullUrl = query('templates').full();
console.log(fullUrl); // Full URL with query string
This library is written in TypeScript and aims to provide as much type safety as possible for query building, ensuring that you can use autocompletion and type checking while constructing your queries. More support for type safety is hopefully coming in the future.
To run the tests for this library, use the following command:
npm test
The library includes tests for various query operations, including filtering, sorting, pagination, and relation population.
Contributions are welcome! If you have ideas for new features or improvements, please open an issue or submit a pull request on GitHub.
This project is licensed under the MIT License. See the LICENSE file for details.