How do I handle message schema changes over time?
Use Message Type versioning to handle schema evolution—create new versions ("PurchaseOrder#2.0") when schemas change, maintain backward compatibility with existing logs, update Search Field Expressions for new versions.
The Challenge: Schemas Evolve
Real-world scenario: PurchaseOrder message adds new field "ShippingMethod" in 2026:
Version 1.0 (2025):
<Order>
<OrderId>PO-12345</OrderId>
<CustomerId>ACME</CustomerId>
<OrderAmount>1500.00</OrderAmount>
</Order>
Version 2.0 (2026):
<Order>
<OrderId>PO-12345</OrderId>
<CustomerId>ACME</CustomerId>
<OrderAmount>1500.00</OrderAmount>
<ShippingMethod>Express</ShippingMethod> <!-- NEW FIELD -->
</Order>
Problem: Search Field Expressions for "PurchaseOrder#1.0" don't extract ShippingMethod—business users can't search by shipping method for new orders.
Solution: Message Type Versioning
Step 1: Create New Message Type Version
In Nodinite Administration → Repository → Message Types:
- Copy existing Message Type - Clone "PurchaseOrder#1.0" → "PurchaseOrder#2.0"
- Update description - Document schema changes: "Added ShippingMethod field, expanded Customer data"
- Save new version
Step 2: Update Integration Code
Update OriginalMessageTypeName in JSON Log Event when logging new schema:
{
"LogAgentValueId": 42,
"EndPointName": "Custom Integration - Receive Orders",
"OriginalMessageTypeName": "PurchaseOrder#2.0", // Changed from 1.0 → 2.0
"ApplicationInterchangeId": "a1b2c3d4-e5f6-7890",
"Body": "<Order><OrderId>PO-12345</OrderId>...<ShippingMethod>Express</ShippingMethod></Order>"
}
Gradual rollout: During transition, system logs both versions:
- Old orders (before schema change):
OriginalMessageTypeName: "PurchaseOrder#1.0" - New orders (after schema change):
OriginalMessageTypeName: "PurchaseOrder#2.0"
Step 3: Create New Search Field Expressions
Add Search Field for new ShippingMethod field:
- Navigate to Administration → Log Management → Search Fields
- Create Search Field - Name: "Shipping Method"
- Bind to Message Type "PurchaseOrder#2.0" (not 1.0)
- Configure XPath expression:
/Order/ShippingMethod/text() - Save
Result:
- Version 1.0 logs: Extract OrderId, CustomerId, OrderAmount (3 Search Fields)
- Version 2.0 logs: Extract OrderId, CustomerId, OrderAmount, ShippingMethod (4 Search Fields)
Step 4: Update Existing Search Fields (If Needed)
If field location changes in schema:
Version 1.0: <OrderAmount>1500.00</OrderAmount>
Version 2.0: <Pricing><OrderAmount>1500.00</OrderAmount></Pricing> (moved under <Pricing> element)
Create separate Search Field Expression for PurchaseOrder#2.0:
- Search Field "Order Amount" for PurchaseOrder#1.0: XPath
/Order/OrderAmount/text() - Search Field "Order Amount" for PurchaseOrder#2.0: XPath
/Order/Pricing/OrderAmount/text()(updated path)
Nodinite applies correct expression based on Message Type.
Backward Compatibility
Historical logs with PurchaseOrder#1.0 remain searchable:
- ✅ Search by OrderId, CustomerId, OrderAmount - Works for all logs (both v1.0 and v2.0)
- ⚠️ Search by ShippingMethod - Only works for v2.0 logs (field doesn't exist in v1.0)
Business users understand: "Shipping Method filter only applies to orders logged after 2026-01-15 (when v2.0 deployed)."
Naming Conventions
Best practices for Message Type versioning:
- ✅ Semantic versioning:
{MessageName}#{MajorVersion}.{MinorVersion}PurchaseOrder#1.0- Initial versionPurchaseOrder#1.1- Backward-compatible changes (new optional field)PurchaseOrder#2.0- Breaking changes (renamed/removed fields, different structure)
- ✅ Descriptive names:
CustomerUpdate#2.0,Invoice#3.0,ShipmentNotification#1.1 - ✅ Document changes: In Message Type description field, list differences from previous version
Breaking vs Non-Breaking Changes
Non-Breaking Changes (Increment Minor Version)
Use same major version (1.x → 1.1):
- ✅ Add new optional fields -
<ShippingMethod>added, but not required - ✅ Add new elements - New
<Tracking>section, but old logs don't have it
Existing Search Fields continue working.
Breaking Changes (Increment Major Version)
Use new major version (1.x → 2.0):
- ❌ Rename fields -
<OrderId>renamed to<PurchaseOrderNumber> - ❌ Remove fields -
<LegacyField>deleted - ❌ Restructure - Fields moved under different parent elements
Must create new Search Field Expressions for major version.
Managing Multiple Active Versions
During transition periods, multiple versions co-exist:
- Legacy system: Logs "PurchaseOrder#1.0"
- New system: Logs "PurchaseOrder#2.0"
Log Views can filter both:
- Create Log View: "All Purchase Orders" - includes both Message Types (1.0 + 2.0)
- Create Log View: "Purchase Orders (New Schema)" - filters only Message Type 2.0
Users choose appropriate view based on needs.
Migration Strategy
Gradual Rollout
- Week 1: Deploy new integration version logging "PurchaseOrder#2.0", old version still logs "PurchaseOrder#1.0"
- Week 2-4: Monitor both versions, verify Search Fields extract correctly
- Month 2: Decommission old integration version
Both versions searchable during entire migration.
Big Bang Cutover
- Deploy all integrations simultaneously - Switch from "PurchaseOrder#1.0" → "PurchaseOrder#2.0" in one release
- Historical logs: Remain as "PurchaseOrder#1.0" (immutable)
- New logs: All "PurchaseOrder#2.0"
Clear cutover date, simpler version management.
Retroactive Changes (Re-Indexing)
Can you apply new Search Fields to old logs?
Yes—Nodinite supports re-indexing:
- Create new Search Field Expression for existing Message Type
- Re-index historical logs - Nodinite re-parses message bodies, applies new Search Field
- Result: Historical logs now searchable by newly defined field
Example: Forgot to extract CustomerId when initially logging "PurchaseOrder#1.0". Add Search Field Expression retroactively, re-index last 90 days of logs—now searchable by Customer ID.
Related Topics:
Message Types Overview
Search Field Expressions
Log Views for Filtering
See all FAQs: Troubleshooting Overview
Next Step
Back to Custom Logging Overview