メインコンテンツまでスキップ
バージョン: 0.6.0 (Previous)

🛒 Order Service

Testing Status

The Order Service provides a complete REST API for managing order entities with CRUD operations. It's built using the Nodeblocks functional composition approach and integrates seamlessly with MongoDB.


🚀 Quickstart​

import express from 'express';
import { middlewares, services, drivers } from '@nodeblocks/backend-sdk';

const { nodeBlocksErrorMiddleware } = middlewares;
const { orderService } = services;
const { getMongoClient } = drivers;

const client = getMongoClient('mongodb://localhost:27017', 'dev');

express()
.use(
orderService(
{
orders: client.collection('orders'),
identities: client.collection('identities'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
identity: {
typeIds: {
admin: '100',
guest: '000',
regular: '001',
},
},
}
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));

📋 Endpoint Summary​

Order Operations​

MethodPathDescriptionAuth Required
POST/ordersCreate a new order✅ Required
GET/orders/:orderIdRetrieve an order by ID✅ Required
GET/ordersList/filter orders✅ Required
PATCH/orders/:orderIdUpdate an order✅ Required
DELETE/orders/:orderIdDelete an order✅ Required

🗄️ Entity Schema​

The order entity combines base fields (auto-generated) with complex order-specific data including items array and pricing:

{
"items": [
{
"productId": "string (uuid)",
"quantity": "number",
"price": "number"
}
],
"total": "number",
"subtotal": "number",
"tax": "number",
"currency": "string",
"status": "string",
"identityId": "string (uuid)",
"organizationId": "string (uuid)",
"createdAt": "string (datetime)",
"id": "string",
"updatedAt": "string (datetime)"
}

Field Details​

FieldTypeAuto-GeneratedRequiredDescription
itemsarray❌✅Array of order items with product details
totalnumber❌✅Total order amount (minimum 0)
subtotalnumber❌❌Subtotal before tax (minimum 0)
taxnumber❌❌Tax amount (minimum 0)
currencystring❌❌Currency code (e.g., "USD", "EUR")
statusstring❌❌Order status (e.g., "pending", "completed")
identityIdstring (uuid)❌✅Identity who placed the order
organizationIdstring (uuid)❌❌Organization associated with the order
createdAtdatetime✅✅Creation timestamp
idstring✅✅Unique identifier (UUID)
updatedAtdatetime✅✅Last modification timestamp

Items Array Schema​

Each item in the items array must contain:

FieldTypeRequiredValidationDescription
productIdstring (uuid)✅UUID formatProduct identifier
quantitynumber✅Minimum 1Quantity ordered
pricenumber✅Minimum 0Price per unit

📝 Note: The schema enforces additionalProperties: false, meaning only defined fields are allowed. Auto-generated fields are set by the service and should not be included in create/update requests.


🔐 Authentication Headers​

For all endpoints, include the following headers:

Authorization: Bearer <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 Order​

Creates a new order with the provided information including items array and pricing details.

Request:

  • Method: POST
  • Path: /orders
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Request Body:

FieldTypeRequiredDescription
itemsarray✅Array of order items (see Items Schema)
totalnumber✅Total order amount
identityIdstring (uuid)✅Identity who placed the order
subtotalnumber❌Subtotal before tax
taxnumber❌Tax amount
currencystring❌Currency code
statusstring❌Order status
organizationIdstring (uuid)❌Organization associated with order

Response Body:

FieldTypeDescription
itemsarrayArray of order items with product details
items[].productIdstringProduct identifier
items[].quantitynumberQuantity ordered
items[].pricenumberPrice per unit
totalnumberTotal order amount
subtotalnumberSubtotal before tax
taxnumberTax amount
currencystringCurrency code
statusstringOrder status
identityIdstringIdentity who placed the order
organizationIdstringOrganization associated with order
createdAtstringCreation timestamp
idstringUnique order identifier
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: Enforced automatically (items, total, identityId required)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or self (order owner)

Authorization Note: When creating an order, the identityId field in the request body must match the identityId associated with your access token. If you attempt to create an order for a different identity, you will receive a 403 Forbidden error.

Admin users cannot create orders for other users unless the backend validator logic is changed to allow this.

Example Request:

curl -X POST http://localhost:8089/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-d '{
"identityId": "30000000-0000-4000-a000-000000000001",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"currency": "USD",
"status": "pending",
"organizationId": "20000000-0000-4000-a000-000000000001"
}'

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "pending",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-04T01:59:20.084Z"
}

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 'identityId'",
"request body must have required property 'items'"
]
}
}

When authentication fails:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "token could not be verified"
}
}

When authorization fails:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
"error": {
"message": "User is not authorized to access this order"
}
}

2. Get Order by ID​

Retrieves a specific order by its unique ID.

Request:

  • Method: GET
  • Path: /orders/:orderId
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

URL Parameters:

ParameterTypeRequiredDescription
orderIdstring✅Unique order identifier

Response Body:

FieldTypeDescription
itemsarrayArray of order items with product details
items[].productIdstringProduct identifier
items[].quantitynumberQuantity ordered
items[].pricenumberPrice per unit
totalnumberTotal order amount
subtotalnumberSubtotal before tax
taxnumberTax amount
currencystringCurrency code
statusstringOrder status
identityIdstringIdentity who placed the order
organizationIdstringOrganization associated with order
createdAtstringCreation timestamp
idstringUnique order identifier
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: None (GET request)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or order ownership

Example Request:

curl http://localhost:8089/orders/10283907-d41a-4647-a235-18ec63f3369a \
-H "Authorization: Bearer <access_token>"

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "completed",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-07T08:11:16.176Z"
}

Error Responses:

When no order exists with the provided ID:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Order not found"
}
}

3. List Orders​

Retrieves a list of orders with optional filtering and pagination.

Request:

  • Method: GET
  • Path: /orders
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

Query Parameters:

ParameterTypeRequiredDescription
currencystring❌Filter by currency
organizationIdstring❌Filter by organization
statusstring❌Filter by status
subtotalnumber❌Filter by subtotal amount
taxnumber❌Filter by tax amount
totalnumber❌Filter by total amount
identityIdstring❌Filter by identityId
pagenumber❌Page number for pagination
limitnumber❌Number of items per page

Response Body:

FieldTypeDescription
itemsarrayArray of order items with product details
items[].productIdstringProduct identifier
items[].quantitynumberQuantity ordered
items[].pricenumberPrice per unit
totalnumberTotal order amount
subtotalnumberSubtotal before tax
taxnumberTax amount
currencystringCurrency code
statusstringOrder status
identityIdstringIdentity who placed the order
organizationIdstringOrganization associated with order
createdAtstringCreation timestamp
idstringUnique order identifier
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: None (GET request)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or self

Example Requests:

List all orders:

curl http://localhost:8089/orders \
-H "Authorization: Bearer <access_token>"

Filter by status:

curl "http://localhost:8089/orders?status=completed" \
-H "Authorization: Bearer <access_token>"

Filter by currency:

curl "http://localhost:8089/orders?currency=USD" \
-H "Authorization: Bearer <access_token>"

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "completed",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-07T08:11:16.176Z"
}
]

4. Update Order​

Updates an existing order with partial data.

Request:

  • Method: PATCH
  • Path: /orders/:orderId
  • Headers:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

URL Parameters:

ParameterTypeRequiredDescription
orderIdstring✅Unique order identifier

Request Body (all fields optional):

FieldTypeRequiredDescription
itemsarray❌Array of order items
totalnumber❌Total order amount
subtotalnumber❌Subtotal before tax
taxnumber❌Tax amount
currencystring❌Currency code
statusstring❌Order status
identityIdstring (uuid)❌Identity who placed the order
organizationIdstring (uuid)❌Organization associated with order

Response Body:

FieldTypeDescription
itemsarrayArray of order items with product details
items[].productIdstringProduct identifier
items[].quantitynumberQuantity ordered
items[].pricenumberPrice per unit
totalnumberUpdated total order amount
subtotalnumberUpdated subtotal before tax
taxnumberUpdated tax amount
currencystringUpdated currency code
statusstringUpdated order status
identityIdstringIdentity who placed the order
organizationIdstringUpdated organization associated with order
createdAtstringCreation timestamp
idstringUnique order identifier
updatedAtstringLast update timestamp

Validation:

  • Schema Validation: Enforced automatically (partial updates, all fields optional)
  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or order ownership

Example Request:

curl -X PATCH http://localhost:8089/orders/10283907-d41a-4647-a235-18ec63f3369a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-d '{"status": "completed"}'

Success Response:

HTTP/1.1 200 OK
Content-Type: application/json

{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "completed",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-07T08:11:16.176Z"
}

Error Responses:

When no order exists with the provided ID:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Order not found"
}
}

5. Delete Order​

Permanently deletes an order from the system.

Request:

  • Method: DELETE
  • Path: /orders/:orderId
  • Headers:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • Authorization: Bearer token required

URL Parameters:

ParameterTypeRequiredDescription
orderIdstring✅Unique order identifier

Response Body:

FieldTypeDescription
No response body-Delete endpoint returns no response body on success

Validation:

  • Route Validators:
    • Require authenticated request (bearer token)
    • Require admin role or order ownership

Example Request:

curl -X DELETE http://localhost:8089/orders/10283907-d41a-4647-a235-18ec63f3369a \
-H "Authorization: Bearer <access_token>"

Success Response:

HTTP/1.1 204 No Content

Error Responses:

When no order exists with the provided ID:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Order not found"
}
}

⚙️ Configuration Options​

Service Configuration​

interface OrderServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT encryption secret
authSignSecret: string; // JWT signing secret
};
identity?: {
typeIds?: {
admin: string; // Admin user type identifier
guest: string; // Guest user type identifier
regular: string; // Regular user type identifier
};
};
}

Configuration Details​

The order 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 encryption
    • authSignSecret: Secret key for JWT signature verification

👥 User Type Settings​

identity.typeIds - User type identifier configuration

  • Type: { admin?: string; guest?: string; regular?: 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"
    • 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"
    • user: Regular user type identifier
      • Type: string
      • Description: Custom identifier for regular users
      • Use Case: Standard user access permissions
      • Example: "user", "member", "customer"

Example Configuration​

const orderConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret'
},
identity: {
typeIds: {
admin: 'administrator',
guest: 'visitor',
regular: 'member'
}
}
};

🚨 Error Handling​

All order service errors return JSON format with appropriate HTTP status codes:

Common Error Codes​

StatusError MessageDescription
400Validation ErrorInvalid request body format or missing required fields
400request body must have required property 'identityId'Missing identityId field in request body
400request body must have required property 'items'Missing items array in request body
400request body must have required property 'total'Missing total field in request body
400request body must NOT have additional propertiesRequest contains unsupported fields
400Failed to create orderDatabase insert operation failed to return an inserted ID
400Failed to update orderUpdate operation doesn't modify any data (no changes detected)
400Failed to delete orderDatabase deletion operation failed
401token could not be verifiedMissing or invalid authorization token
401Authentication failedMissing or invalid authentication token
401Token fails security checkToken security validation failed
403User is not authorized to access this orderUser lacks required permissions (admin/owner access)
403User is not authorized to access this resourceUser lacks required permissions (admin access)
404Order not foundOrder doesn't exist for the requested operation
500Failed to create orderDatabase connection issues or unexpected failures during creation
500Failed to get orderDatabase connection issues or unexpected failures during retrieval
500Failed to find ordersDatabase connection issues, invalid filter syntax, or unexpected failures during listing
500Failed to update orderDatabase connection issues or unexpected failures during update
500Failed to delete orderDatabase connection issues or unexpected failures during deletion

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 'items'",
"request body must have required property 'total'"
]
}
}