Get Product List
The getProductsList
function performs comprehensive product search operations with advanced filtering, faceted navigation, and pagination capabilities. This function serves as the primary search engine for the e-commerce platform, enabling users to discover products through text search, attribute filtering, brand selection, and supplier restrictions.
The function supports sophisticated search scenarios including full-text search across product names, descriptions, and SKUs, combined with multi-dimensional filtering through attributes, brands, suppliers, and product tags. It provides faceted navigation data to enable dynamic filter interfaces and supports efficient pagination for handling large result sets.
This function is critical for B2B e-commerce scenarios where buyers need to quickly locate specific products from extensive catalogs, compare offerings across suppliers, and apply complex business-specific filtering criteria for procurement workflows.
Process Flow
sequenceDiagram participant User as User participant Component as Vue Component participant useSearchProduct as useSearchProduct participant SDK as Djust SDK participant API as API Server participant Auth as Auth Service User->>Component: Enter Search Criteria Component->>useSearchProduct: getProductsList(params) useSearchProduct->>useSearchProduct: Build Search Parameters useSearchProduct->>SDK: useFetch('/api/search/products') SDK->>Auth: Verify Authentication Token Auth-->>SDK: Token Valid SDK->>API: GET /api/search/products alt Success Response API-->>SDK: 200 - Search Results + Facets SDK-->>useSearchProduct: SearchProductsResponse useSearchProduct->>useSearchProduct: Process Results & Facets useSearchProduct-->>Component: Products + Pagination + Filters Component-->>User: Display Search Results else No Results Found API-->>SDK: 200 - Empty Results SDK-->>useSearchProduct: Empty Response useSearchProduct-->>Component: Empty Results Component-->>User: "No products found" else Authentication Error Auth-->>SDK: 401 - Unauthorized SDK-->>useSearchProduct: Auth Error useSearchProduct-->>Component: Authentication Error Component-->>User: Redirect to Login else Permission Error API-->>SDK: 403 - Search Access Denied SDK-->>useSearchProduct: Permission Error useSearchProduct-->>Component: Access Denied Component-->>User: "Search access restricted" else Server Error API-->>SDK: 500 - Internal Error SDK-->>useSearchProduct: Server Error useSearchProduct->>useSearchProduct: Log Server Error useSearchProduct-->>Component: Error Response Component-->>User: "Search service unavailable" end
Call Parameters
The function accepts a SearchProductsRequest
object with the following structure:
SearchProductsRequest Interface (from SDK)
interface SearchProductsRequest {
locale?: string;
filters?: SearchFilters;
pageable?: Pageable;
includeFacets?: boolean;
}
interface SearchFilters {
currency?: string;
locale?: string;
brand?: string[];
attributes?: string[];
productTags?: string[];
suppliers?: string[];
aggregation?: AggregationType;
query?: string;
categoryIds?: string[];
priceRange?: PriceRange;
}
interface Pageable {
page?: number;
size?: number;
sort?: string[];
}
interface PriceRange {
min?: number;
max?: number;
currency?: string;
}
enum AggregationType {
PRODUCT = "PRODUCT",
VARIANT = "VARIANT",
OFFER = "OFFER",
}
Parameter Details
| Parameter | Type | Required | Default | Example | Business Impact |
| --------------------- | ----------------- | ----------- | -------------- | ----------------------------- | --------------------------------------------------------------- | ------------ | ------ | ------------------------------------- |
| locale
| string
| ❌ Optional | Runtime config | "en-GB"
, "fr-FR"
| Localization: Affects search relevance and content language |
| filters.query
| string
| ❌ Optional | - | "laptop dell i7"
| Search Scope: Text search across product content |
| filters.currency
| string
| ❌ Optional | Runtime config | "EUR"
, "USD"
| Pricing: Currency context for price filtering |
| filters.brand
| string[]
| ❌ Optional | []
| ["Dell", "HP"]
| Brand Filtering: Restricts results to specific brands |
| filters.attributes
| string[]
| ❌ Optional | []
| ["RAM:16GB", "Color:Black"]
| Attribute Filtering: Product specification filtering |
| filters.suppliers
| string[]
| ❌ Optional | []
| ["supplier-001"]
| Supplier Filtering: Business relationship filtering |
| filters.productTags
| string[]
| ❌ Optional | []
| ["electronics", "business"]
| Category Filtering: Tag-based product grouping |
| filters.aggregation
| AggregationType
| ❌ Optional | PRODUCT
| PRODUCT
, VARIANT
| Data Scope: Result aggregation level |
| pageable.page
| number
| ❌ Optional | 0
| 0
, 1
, 2
| Performance: Controls pagination |
| pageable.size
| number
| ❌ Optional | 20
| 10
, 20
, 50
| Performance: Results per page |
| pageable.sort
| string[]
| ❌ Optional | ["name | ASC"]
| ["price | DESC", "name | ASC"]
| Ordering: Result sorting criteria |
| includeFacets
| boolean
| ❌ Optional | true
| true
, false
| Performance: Include faceting data |
Complete Example Call
const searchParams: SearchProductsRequest = {
locale: "en-GB",
filters: {
query: "business laptop",
currency: "EUR",
brand: ["Dell", "HP"],
attributes: ["RAM:16GB", "Storage:SSD"],
productTags: ["business", "professional"],
suppliers: ["supplier-techpro"],
aggregation: AggregationType.PRODUCT,
priceRange: {
min: 500,
max: 2000,
currency: "EUR",
},
},
pageable: {
page: 0,
size: 20,
sort: ["relevance|DESC", "price|ASC"],
},
includeFacets: true,
};
const searchResults = await getProductsList(searchParams);
Returns from Composable
The function returns a SearchProductsResponse
object with the following structure:
SearchProductsResponse Interface (from SDK)
interface SearchProductsResponse {
success: boolean;
products: ProductsSearchList;
facets?: Facets;
includeFacets: boolean;
}
interface ProductsSearchList {
content: ProductSearchContent[];
pageable: Pageable;
totalElements: number;
totalPages: number;
size: number;
number: number;
first: boolean;
last: boolean;
empty?: boolean;
}
interface Facets {
attributes: AttributeFacet[];
suppliers?: SupplierFacet[];
brands?: BrandFacet[];
productTags?: ProductTagFacet[];
customFields?: CustomFieldFacet[];
priceRange?: PriceRangeFacet;
}
interface AttributeFacet {
id: string;
name: string;
values: AttributeValueFacet[];
}
interface AttributeValueFacet {
value: string;
count: number;
selected: boolean;
}
Realistic Example JSON Response
{
"success": true,
"products": {
"content": [
{
"offerPrice": {
"unitPrice": 1299.99,
"currency": "EUR",
"taxIncluded": false
},
"offer": {
"id": "offer-001",
"externalId": "EXT-OFFER-001",
"quantityPerItem": 1,
"stock": 85,
"currency": "EUR",
"minOrderQuantity": 1,
"maxOrderQuantity": 50,
"leadTimeToShip": 3
},
"variant": {
"id": "variant-001",
"externalId": "DELL-LAT-7420-16GB",
"sku": "DELL-LAT-7420-16GB-BLK",
"name": "Dell Latitude 7420 - 16GB RAM - Black",
"description": "Premium business laptop with Intel i7 processor",
"pictureUrls": [
{
"url": "https://cdn.example.com/dell-latitude-7420-main.jpg",
"width": 1200,
"height": 900
}
],
"ean": "1234567890125",
"mpn": "LAT7420-16-BLK"
},
"product": {
"id": "product-001",
"externalId": "DELL-LATITUDE-7420",
"sku": "DELL-LAT-7420",
"name": "Dell Latitude 7420",
"description": "Premium business laptop series with enhanced security features",
"brand": "Dell",
"mainPictureUrl": "https://cdn.example.com/dell-latitude-7420-hero.jpg",
"tags": [
{
"name": "Business",
"category": "USE_CASE"
},
{
"name": "Professional",
"category": "TIER"
}
],
"unit": "piece"
},
"attributes": [
{
"name": "RAM Size",
"externalId": "RAM_SIZE",
"value": "16GB",
"values": ["16GB"]
},
{
"name": "Storage Type",
"externalId": "STORAGE_TYPE",
"value": "SSD",
"values": ["SSD"]
},
{
"name": "Color",
"externalId": "COLOR",
"value": "Black",
"values": ["Black"]
}
],
"supplier": {
"id": "supplier-001",
"name": "TechPro Distribution",
"externalId": "TECH-PRO-001"
}
}
],
"pageable": {
"page": 0,
"size": 20,
"sort": ["relevance|DESC", "price|ASC"]
},
"totalElements": 127,
"totalPages": 7,
"size": 20,
"number": 0,
"first": true,
"last": false,
"empty": false
},
"facets": {
"attributes": [
{
"id": "RAM_SIZE",
"name": "RAM Size",
"values": [
{
"value": "8GB",
"count": 45,
"selected": false
},
{
"value": "16GB",
"count": 67,
"selected": true
},
{
"value": "32GB",
"count": 15,
"selected": false
}
]
},
{
"id": "STORAGE_TYPE",
"name": "Storage Type",
"values": [
{
"value": "SSD",
"count": 98,
"selected": true
},
{
"value": "HDD",
"count": 29,
"selected": false
}
]
}
],
"brands": [
{
"name": "Dell",
"count": 67,
"selected": true
},
{
"name": "HP",
"count": 45,
"selected": true
},
{
"name": "Lenovo",
"count": 15,
"selected": false
}
],
"suppliers": [
{
"name": "TechPro Distribution",
"count": 89,
"selected": true
},
{
"name": "Business Tech Solutions",
"count": 38,
"selected": false
}
],
"productTags": [
{
"id": "business",
"name": "Business",
"count": 127,
"selected": true
},
{
"id": "professional",
"name": "Professional",
"count": 94,
"selected": true
}
],
"priceRange": {
"min": 599.99,
"max": 2899.99,
"currency": "EUR",
"distribution": [
{
"range": "600-1000",
"count": 34
},
{
"range": "1000-1500",
"count": 67
},
{
"range": "1500-2000",
"count": 23
},
{
"range": "2000+",
"count": 3
}
]
}
},
"includeFacets": true
}
Error Management
HTTP Error Codes and Handling
Error Code | Cause | System Action | User Message | Return Format |
---|---|---|---|---|
400 | Invalid search parameters or malformed filters | Log validation error, return empty results | "Invalid search criteria" | { success: false, products: { content: [] } } |
401 | Authentication token missing/invalid | Trigger re-authentication flow | "Please log in to search products" | Authentication redirect |
403 | User lacks search permissions | Log access attempt, return restricted results | "Limited search access" | Filtered results based on permissions |
404 | Search service or endpoint not found | Log service error, return empty results | "Search service unavailable" | { success: false, products: { content: [] } } |
429 | Rate limit exceeded for search requests | Log rate limit hit, return cached results | "Too many search requests" | Cached results or empty |
500 | Internal server error in search service | Log server error, return empty results | "Search temporarily unavailable" | { success: false, products: { content: [] } } |
Error Handling Example Code
// Global error handling in composable
const getProductsList = async ({
locale = defaultLocale,
filters = defaultFilters,
pageable = defaultPageable,
includeFacets = true,
}: SearchProductsRequest) => {
try {
// Input validation
if (filters?.query && filters.query.length > 100) {
console.warn("Search query too long, truncating");
filters.query = filters.query.substring(0, 100);
}
loading.value = true;
const { data, status, error } = await useFetch("/api/search/products", {
params: {
locale,
filters: JSON.stringify(filters),
pageable: JSON.stringify(pageable),
includeFacets: includeFacets,
},
key: `products-${locale}-${JSON.stringify(filters)}-${JSON.stringify(
pageable
)}-${includeFacets}`,
});
loading.value = status.value === "pending";
if (error.value) {
console.error("Error fetching products:", {
locale,
filters,
error: error.value,
});
return {
success: false,
products: { content: [], totalElements: 0 },
facets: undefined,
includeFacets: false,
} as SearchProductsResponse;
}
return (
data.value ||
({
success: false,
products: { content: [], totalElements: 0 },
facets: undefined,
includeFacets: false,
} as SearchProductsResponse)
);
} catch (error) {
console.error("Unexpected error in getProductsList:", error);
return {
success: false,
products: { content: [], totalElements: 0 },
facets: undefined,
includeFacets: false,
} as SearchProductsResponse;
} finally {
loading.value = false;
}
};
// Component-level error handling
const performProductSearch = async (searchCriteria: SearchProductsRequest) => {
try {
isSearching.value = true;
const response = await getProductsList(searchCriteria);
if (!response.success) {
throw new Error("Search request failed");
}
// Process successful response
searchResults.value = response.products.content;
totalResults.value = response.products.totalElements;
currentFacets.value = response.facets;
} catch (error) {
console.error("Product search error:", error);
// User notification
useToast().add({
title: "Search Error",
description: "Unable to perform product search. Please try again.",
color: "red",
});
// Fallback to empty results
searchResults.value = [];
totalResults.value = 0;
currentFacets.value = undefined;
} finally {
isSearching.value = false;
}
};
Use Cases
1. Text-based Product Discovery
Enable users to find products using natural language queries across product names, descriptions, and specifications.
Scenario: User searches for "business laptop with SSD storage" to find suitable professional computing devices.
Parameters: { filters: { query: "business laptop with SSD storage" }, pageable: { page: 0, size: 20 }, includeFacets: true }
Expected Outcome: Relevant business laptops displayed with SSD storage, along with filtering options for further refinement.
2. Advanced Attribute Filtering
Support complex product searches using multiple attribute filters for precise product specification matching.
Scenario: IT procurement manager needs laptops with specific RAM, storage, and color requirements for enterprise deployment.
Parameters: { filters: { attributes: ["RAM:16GB", "Storage:SSD", "Color:Black"], brand: ["Dell", "HP"] } }
Expected Outcome: Filtered results showing only products matching exact specifications with pricing and availability.
3. Supplier-specific Product Search
Enable buyers to search within their approved supplier network for compliance and relationship management.
Scenario: Company policy requires purchases from specific approved suppliers for warranty and support guarantees.
Parameters: { filters: { suppliers: ["approved-supplier-001", "preferred-supplier-002"], query: "monitors" } }
Expected Outcome: Monitor products available only from approved suppliers with negotiated pricing.
4. Faceted Navigation and Refinement
Provide dynamic filtering interface allowing users to progressively refine search results using available facets.
Scenario: User starts with broad "electronics" search and progressively narrows using brand, price range, and attribute facets.
Parameters: { filters: { productTags: ["electronics"] }, includeFacets: true, pageable: { page: 0, size: 24 } }
Expected Outcome: Electronics products with comprehensive facet data enabling progressive search refinement.
Important Points
Performance Considerations
- Intelligent Caching: Search results cached with complex keys including all filter parameters
- Facet Optimization: Conditional facet loading to reduce response size and improve performance
- Pagination Strategy: Efficient pagination handling for large result sets with configurable page sizes
- Query Optimization: Server-side query optimization for complex attribute and text-based searches
Security Aspects
- Permission Filtering: Backend automatically filters results based on user's product access permissions
- Supplier Restrictions: Results limited to user's approved supplier network and contract agreements
- Data Privacy: Sensitive pricing and stock information filtered based on user role and permissions
- Input Sanitization: All search inputs sanitized to prevent injection attacks and ensure data integrity
Flexibility Features
- Multi-language Search: Search adapts to user's locale for language-specific product matching
- Currency-aware Results: Pricing and filtering respects user's preferred currency settings
- Configurable Aggregation: Support for product, variant, or offer-level result aggregation
- Extensible Filtering: Flexible filter system supports new attribute types and business rules
Integration Capabilities
- Analytics Integration: Search behavior tracking for business intelligence and catalog optimization
- Cart Integration: Direct "add to cart" functionality from search results for streamlined purchasing
- Quote Integration: Bulk quote generation from filtered search results for enterprise workflows
- Catalog Management: Search results inform catalog managers about popular products and search patterns
Technical Implementation
Composable Function with Complete JSDoc
/**
* Performs comprehensive product search with filtering and faceted navigation
*
* @param params - Search request parameters
* @param params.locale - Locale for internationalized search
* @param params.filters - Search filters and criteria
* @param params.pageable - Pagination configuration
* @param params.includeFacets - Whether to include faceting data
* @returns Promise resolving to search results with products and facets
*
* @example
* ```typescript
* const { getProductsList } = useSearchProduct();
*
* const searchResults = await getProductsList({
* locale: "en-GB",
* filters: {
* query: "business laptop",
* brand: ["Dell", "HP"],
* attributes: ["RAM:16GB"]
* },
* pageable: { page: 0, size: 20 },
* includeFacets: true
* });
*
* if (searchResults.success) {
* console.log('Products found:', searchResults.products.totalElements);
* console.log('Available facets:', Object.keys(searchResults.facets || {}));
* }
* ```
*
* @throws {Error} When network request fails or invalid parameters provided
* @since 1.0.0
*/
const getProductsList = async ({
locale = defaultLocale,
filters = defaultFilters,
pageable = defaultPageable,
includeFacets = true,
}: SearchProductsRequest): Promise<SearchProductsResponse> => {
try {
// Input validation and sanitization
if (filters?.query && filters.query.length > 200) {
console.warn("Search query exceeds maximum length, truncating");
filters.query = filters.query.substring(0, 200);
}
// Set loading state
loading.value = true;
// Runtime configuration for defaults
const runtimeConfig = useRuntimeConfig();
const effectiveLocale = locale || runtimeConfig.public.locale;
const effectiveCurrency =
filters?.currency || runtimeConfig.public.currency;
const { data, status, error } = await useFetch("/api/search/products", {
params: {
locale: effectiveLocale,
filters: JSON.stringify({
...defaultFilters,
...filters,
currency: effectiveCurrency,
}),
pageable: JSON.stringify({
...defaultPageable,
...pageable,
}),
includeFacets: includeFacets,
},
// Generate unique cache key
key: `products-${effectiveLocale}-${JSON.stringify(
filters
)}-${JSON.stringify(pageable)}-${includeFacets}`,
});
// Update loading state
loading.value = status.value === "pending";
if (error.value) {
console.error("Error fetching products:", {
locale: effectiveLocale,
filters,
pageable,
error: error.value,
});
return {
success: false,
products: {
content: [],
totalElements: 0,
totalPages: 0,
size: pageable?.size || 20,
number: pageable?.page || 0,
first: true,
last: true,
empty: true,
},
facets: undefined,
includeFacets: false,
} as SearchProductsResponse;
}
return (
data.value ||
({
success: false,
products: { content: [], totalElements: 0 },
facets: undefined,
includeFacets: false,
} as SearchProductsResponse)
);
} catch (error) {
console.error("Unexpected error in getProductsList:", error);
return {
success: false,
products: { content: [], totalElements: 0 },
facets: undefined,
includeFacets: false,
} as SearchProductsResponse;
} finally {
loading.value = false;
}
};
Execution Flow
Step-by-Step Process
-
Parameter Validation and Sanitization
// Validate and clean search parameters if (filters?.query && filters.query.length > 200) { filters.query = filters.query.substring(0, 200); }
-
Loading State Management
// Set loading indicator for UI feedback loading.value = true;
-
Configuration Setup
// Apply runtime defaults and merge parameters const runtimeConfig = useRuntimeConfig(); const effectiveLocale = locale || runtimeConfig.public.locale; const mergedFilters = { ...defaultFilters, ...filters };
-
Cache Key Generation
// Generate comprehensive cache key const cacheKey = `products-${locale}-${JSON.stringify( filters )}-${JSON.stringify(pageable)}-${includeFacets}`;
-
API Request Construction
// Build search API request const requestParams = { locale: effectiveLocale, filters: JSON.stringify(mergedFilters), pageable: JSON.stringify(mergedPageable), includeFacets: includeFacets, };
-
Search Execution
// Execute product search request const { data, status, error } = await useFetch("/api/search/products", { params: requestParams, key: cacheKey, });
-
Response Processing
// Handle search results or errors if (error.value) { logError("Product search failed", { filters, error: error.value }); return emptySearchResponse; }
-
Result Formatting
// Return formatted search response return { success: true, products: data.value.products, facets: data.value.facets, includeFacets: includeFacets, };
-
State Cleanup
// Reset loading state loading.value = false;
Updated about 2 months ago