📦 Product Service
The Product Service provides a complete REST API for managing product entities with comprehensive CRUD operations and powerful batch processing capabilities. It's built using the Nodeblocks functional composition approach and integrates seamlessly with MongoDB.
🚀 Quickstart
import express from 'express';
import { MongoClient } from 'mongodb';
import { middlewares, services } from '@nodeblocks/backend-sdk';
const { nodeBlocksErrorMiddleware } = middlewares;
const { productService } = services;
const client = new MongoClient('mongodb://localhost:27017').db('dev');
express()
.use(
productService(
{
products: client.collection('products'),
identity: client.collection('identity'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
user: {
typeIds: {
admin: '100',
guest: '000',
user: '001',
},
},
}
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));
📋 Endpoint Summary
Individual Product Operations
Method | Path | Description | Authorization |
---|---|---|---|
POST | /products | Create a new product | Bearer token required (admin only) |
GET | /products/:productId | Retrieve a product by ID | None required |
GET | /products | List/filter products | None required |
PATCH | /products/:productId | Update a product | Bearer token required (admin only) |
DELETE | /products/:productId | Delete a product | Bearer token required (admin only) |
POST | /products/:productId/copy | Copy an existing product | Bearer token required (admin only) |
Batch Product Operations
Method | Path | Description | Authorization |
---|---|---|---|
POST | /products/batch | Create multiple products | Bearer token required (admin only) |
PATCH | /products/batch | Update multiple products | Bearer token required (admin only) |
DELETE | /products/batch | Delete multiple products | Bearer token required (admin only) |
POST | /products/batch/copy | Copy multiple products | Bearer token required (admin only) |
🗄️ Entity Schema
The product entity combines base fields (auto-generated) with product-specific data:
{
"name": "string",
"description": "string",
"createdAt": "string (datetime)",
"id": "string",
"updatedAt": "string (datetime)"
}
Field Details
Field | Type | Auto-Generated | Required | Description |
---|---|---|---|---|
name | string | ❌ | ✅ | Product name |
description | string | ❌ | ✅ | Product description |
createdAt | datetime | ✅ | ✅ | Creation timestamp |
id | string | ✅ | ✅ | Unique identifier (UUID) |
updatedAt | datetime | ✅ | ✅ | Last modification timestamp |
📝 Note: Auto-generated fields are set by the service and should not be included in create/update requests. Field order in responses matches the actual API output.
🔐 Authentication Headers
For protected endpoints, include the following headers:
Authorization: Bearer <admin_access_token>
x-nb-fingerprint: <device_fingerprint>
⚠️ Important: The
x-nb-fingerprint
header is required for all authenticated requests if fingerprint was specified during authorization. Without it, requests will return 401 Unauthorized.
🔧 API Endpoints
1. Create Product
Creates a new product with the provided information.
Request:
- Method:
POST
- Path:
/products
- Headers:
Content-Type: application/json
,Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
Request Body:
Field | Type | Required | Description |
---|---|---|---|
name | string | ✅ | Product name |
description | string | ✅ | Product description |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique product identifier |
name | string | Product name |
description | string | Product description |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Enforced automatically (name, description required)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X POST {{host}}/products \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"name": "Premium Widget",
"description": "High-quality widget for enterprise use"
}'
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "Premium Widget",
"description": "High-quality widget for enterprise use",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}
Error Responses:
When request body is missing required fields:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'description'"
]
}
}
When database insert operation fails:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Failed to create product"
}
}
2. Get Product by ID
Retrieves a specific product by their unique ID.
Request:
- Method:
GET
- Path:
/products/:productId
- Authorization: None required
URL Parameters:
Parameter | Type | Required | Description |
---|---|---|---|
productId | string | ✅ | Unique product identifier |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique product identifier |
name | string | Product name |
description | string | Product description |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Path parameter validation (productId required)
- Route Validators: None
Example Request:
curl {{host}}/products/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "Premium Widget",
"description": "High-quality widget for enterprise use",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}
Error Responses:
When no product exists with the provided ID:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Product not found"
}
}
3. List Products
Retrieves a list of products with optional filtering and pagination.
Request:
- Method:
GET
- Path:
/products
- Authorization: None required
Query Parameters:
Parameter | Type | Required | Description |
---|---|---|---|
name | string | ❌ | Filter by product name |
description | string | ❌ | Filter by product description |
page | number | ❌ | Page number for pagination |
limit | number | ❌ | Number of items per page |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique product identifier |
name | string | Product name |
description | string | Product description |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Query parameter validation (optional name, description, page, limit)
- Route Validators: None
Example Requests:
List all products:
curl {{host}}/products
Filter by name:
curl "{{host}}/products?name=Premium%20Widget"
With pagination:
curl "{{host}}/products?page=1&limit=10"
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"name": "Premium Widget",
"description": "Updated high-quality widget for enterprise use",
"createdAt": "2025-06-24T06:39:17.101Z",
"id": "3d0e4b74-398c-43e2-a7b4-c9a180477322",
"updatedAt": "2025-06-24T06:39:17.101Z"
},
{
"name": "Product A",
"description": "Updated batch description",
"createdAt": "2025-06-24T06:39:45.378Z",
"id": "0e0dd6c7-c3d5-49e5-a1d8-20daa34d380a",
"updatedAt": "2025-06-24T06:39:55.720Z"
},
{
"name": "Product B",
"description": "Updated batch description",
"createdAt": "2025-06-24T06:39:45.378Z",
"id": "d5a60fdf-2a22-4fcc-8e40-a68cb89cce72",
"updatedAt": "2025-06-24T06:39:55.720Z"
}
]
4. Update Product
Updates an existing product with partial data.
Request:
- Method:
PATCH
- Path:
/products/:productId
- Headers:
Content-Type: application/json
,Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
URL Parameters:
Parameter | Type | Required | Description |
---|---|---|---|
productId | string | ✅ | Unique product identifier |
Request Body (all fields optional):
Field | Type | Required | Description |
---|---|---|---|
name | string | ❌ | Product name |
description | string | ❌ | Product description |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique product identifier |
name | string | Updated product name |
description | string | Updated product description |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Enforced automatically (partial updates, all fields optional, no additional properties allowed)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X PATCH {{host}}/products/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{"description": "Updated high-quality widget for enterprise use"}'
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "Premium Widget",
"description": "Updated high-quality widget for enterprise use",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T14:22:15.789Z"
}
Error Responses:
When no product exists with the provided ID:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Product not found"
}
}
5. Delete Product
Permanently deletes a product from the system.
Request:
- Method:
DELETE
- Path:
/products/:productId
- Headers:
Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
URL Parameters:
Parameter | Type | Required | Description |
---|---|---|---|
productId | string | ✅ | Unique product identifier |
Response Body:
Field | Type | Description |
---|---|---|
No response body | - | Delete endpoint returns no response body on success |
Validation:
- Schema Validation: Path parameter validation (productId required)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X DELETE {{host}}/products/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2 \
-H "Authorization: Bearer <access-token>"
Success Response:
HTTP/1.1 204 No Content
Error Responses:
When no product exists with the provided ID:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Product not found"
}
}
6. Copy Product
Creates a copy of an existing product with a new ID.
Request:
- Method:
POST
- Path:
/products/:productId/copy
- Headers:
Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
URL Parameters:
Parameter | Type | Required | Description |
---|---|---|---|
productId | string | ✅ | ID of product to copy |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique identifier for the copied product |
name | string | Product name (copied from original) |
description | string | Product description (copied from original) |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Path parameter validation (productId required)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X POST {{host}}/products/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/copy \
-H "Authorization: Bearer <access-token>"
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "9abc123f-1cd8-4def-b123-456789abcdef",
"name": "Premium Widget",
"description": "High-quality widget for enterprise use",
"createdAt": "2024-05-28T15:30:45.123Z",
"updatedAt": "2024-05-28T15:30:45.123Z"
}
Error Responses:
When no product exists with the provided ID:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Product not found"
}
}
🔄 Batch Product Operations
The Product Service provides powerful batch operations for managing multiple products efficiently.
7. Create Multiple Products
Creates multiple products in a single request.
Request:
- Method:
POST
- Path:
/products/batch
- Headers:
Content-Type: application/json
,Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
Request Body:
Array of product objects, each requiring name
and description
.
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique product identifier |
name | string | Product name |
description | string | Product description |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Enforced automatically (array of product objects with required name and description)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X POST {{host}}/products/batch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '[
{
"name": "Product A",
"description": "Description for Product A"
},
{
"name": "Product B",
"description": "Description for Product B"
}
]'
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"name": "Product A",
"description": "Description for Product A",
"createdAt": "2025-06-24T06:39:45.378Z",
"id": "0e0dd6c7-c3d5-49e5-a1d8-20daa34d380a",
"updatedAt": "2025-06-24T06:39:45.378Z"
},
{
"name": "Product B",
"description": "Description for Product B",
"createdAt": "2025-06-24T06:39:45.378Z",
"id": "d5a60fdf-2a22-4fcc-8e40-a68cb89cce72",
"updatedAt": "2025-06-24T06:39:45.378Z"
}
]
8. Update Multiple Products
Updates multiple products with the same data in a single request.
Request:
- Method:
PATCH
- Path:
/products/batch
- Headers:
Content-Type: application/json
,Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
Request Body:
Field | Type | Required | Description |
---|---|---|---|
ids | array of strings | ✅ | Array of product IDs to update |
data | object | ✅ | Update data to apply to all products |
data.name | string | ❌ | New product name |
data.description | string | ❌ | New product description |
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique product identifier |
name | string | Updated product name |
description | string | Updated product description |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Enforced automatically (ids array and data object required)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X PATCH {{host}}/products/batch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"ids": [
"7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"8fec096b-1bc7-5bfe-c827-3600e8fe2790"
],
"data": {
"description": "Updated batch description"
}
}'
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "Product A",
"description": "Updated batch description",
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T15:45:12.789Z"
},
{
"id": "8fec096b-1bc7-5bfe-c827-3600e8fe2790",
"name": "Product B",
"description": "Updated batch description",
"createdAt": "2024-05-28T09:41:23.123Z",
"updatedAt": "2024-05-28T15:45:12.789Z"
}
]
9. Delete Multiple Products
Deletes multiple products in a single request.
Request:
- Method:
DELETE
- Path:
/products/batch
- Headers:
Content-Type: application/json
,Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
Request Body: Array of product IDs to delete.
Response Body:
Field | Type | Description |
---|---|---|
No response body | - | Delete endpoint returns no response body on success |
Validation:
- Schema Validation: Enforced automatically (array of strings)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X DELETE {{host}}/products/batch \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '[
"7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"8fec096b-1bc7-5bfe-c827-3600e8fe2790"
]'
Success Response:
HTTP/1.1 204 No Content
10. Copy Multiple Products
Creates copies of multiple products in a single request.
Request:
- Method:
POST
- Path:
/products/batch/copy
- Headers:
Content-Type: application/json
,Authorization: Bearer <access-token>
- Authorization: Bearer token required (admin only)
Request Body: Array of product IDs to copy.
Response Body:
Field | Type | Description |
---|---|---|
id | string | Unique identifier for the copied product |
name | string | Product name (copied from original) |
description | string | Product description (copied from original) |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
Validation:
- Schema Validation: Enforced automatically (array of strings)
- Route Validators:
verifyAuthentication(getBearerTokenInfo)
- Ensures valid authentication token is providedvalidateResourceAccess(['admin'], getBearerTokenInfo)
- Requires identity to have admin access
Example Request:
curl -X POST {{host}}/products/batch/copy \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '[
"7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"8fec096b-1bc7-5bfe-c827-3600e8fe2790"
]'
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"id": "9abc123f-1cd8-4def-b123-456789abcdef",
"name": "Product A",
"description": "Description for Product A",
"createdAt": "2024-05-28T16:00:00.000Z",
"updatedAt": "2024-05-28T16:00:00.000Z"
},
{
"id": "def456a1-2e3f-4567-8901-23456789bcde",
"name": "Product B",
"description": "Description for Product B",
"createdAt": "2024-05-28T16:00:00.100Z",
"updatedAt": "2024-05-28T16:00:00.100Z"
}
]
⚙️ Configuration Options
Service Configuration
interface ProductServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT encryption secret
authSignSecret: string; // JWT signing secret
};
user?: {
typeIds?: {
admin: string; // Admin user type identifier
guest: string; // Guest user type identifier
user: string; // Regular user type identifier
};
};
}
Configuration Details
The product service configuration is organized into logical groups for security and user type management.
🔐 Security Settings
authSecrets
- JWT token security secrets
- Type:
{ authEncSecret: string; authSignSecret: string }
- Description: Secret keys for JWT encryption and signing (used for token validation)
- Required: Yes (for production)
- Child Properties:
authEncSecret
: Secret key for JWT payload encryptionauthSignSecret
: Secret key for JWT signature verification
👥 User Type Settings
user.typeIds
- User type identifier configuration
- Type:
{ admin?: string; guest?: string; user?: string }
- Description: Custom user type identifiers for role-based access control
- Default:
undefined
(uses default type validation) - Child Properties:
admin
: Admin user type identifier- Type:
string
- Description: Custom identifier for admin users
- Use Case: Role-based access control for administrative operations
- Example:
"admin"
,"administrator"
,"superuser"
- Type:
guest
: Guest user type identifier- Type:
string
- Description: Custom identifier for guest users
- Use Case: Limited access for unauthenticated or temporary users
- Example:
"guest"
,"visitor"
,"anonymous"
- Type:
user
: Regular user type identifier- Type:
string
- Description: Custom identifier for regular users
- Use Case: Standard user access permissions
- Example:
"user"
,"member"
,"customer"
- Type:
Example Configuration
const productConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret'
},
user: {
typeIds: {
admin: '100',
guest: '000',
user: '001'
}
}
};
🚨 Error Handling
All product service errors return JSON format with appropriate HTTP status codes:
Common Error Codes
Status | Error Message | Description |
---|---|---|
400 | Validation Error | Invalid request body format or missing required fields |
400 | Failed to create product | Database insert operation failed to return an inserted ID |
400 | Failed to update product | Update operation doesn't modify any data (no changes detected) |
400 | Failed to create products | Batch creation operation failed |
400 | Failed to update products | Batch update operation failed |
400 | Failed to delete products | Batch deletion operation failed |
400 | Failed to copy product | Product copy operation failed |
400 | Failed to copy products | Batch copy operation failed |
401 | token could not be verified | Missing or invalid authorization token |
403 | User is not authorized to access this resource | User lacks required permissions (admin access) |
404 | Product not found | Product doesn't exist for the requested operation |
500 | Failed to create product | Database connection issues or unexpected failures during creation |
500 | Failed to get product | Database connection issues or unexpected failures during retrieval |
500 | Failed to find products | Database connection issues, invalid filter syntax, or unexpected failures during listing |
500 | Failed to update product | Database connection issues or unexpected failures during update |
500 | Failed to delete product | Database connection issues or unexpected failures during deletion |
500 | Failed to copy product | Database connection issues or unexpected failures during copying |
Error Response Format
{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}
Validation Errors include additional details:
{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'description'"
]
}
}
🔗 Related Documentation
- User Service - User management operations
- Organization Service - Organization management operations
- Authentication Service - Authentication and authorization
- Error Handling - Understanding error patterns
- Schema Component - Data validation concepts
- Custom Service Tutorial - Build your own services