Overview
Middleware allows you to intercept state changes in JSON Forms before they are applied. This enables you to:- Transform or validate data before updates
- Log state changes for debugging
- Implement custom business logic
- Prevent certain updates
- Synchronize with external systems
Middleware Type
The middleware interface is defined as:Parameters
state: The current JSON Forms stateaction: The action being dispatcheddefaultReducer: The default reducer function to apply the action
Returns
The new state after applying the middleware logic and optionally the default reducer.Default Middleware
The default middleware simply calls the default reducer:Using Middleware
Provide your middleware to JSON Forms:JsonFormsCore State
TheJsonFormsCore state contains:
CoreActions Type
Actions include data updates, initialization, and other state changes. The exact structure depends on the action type.Middleware Examples
Logging Middleware
Log all state changes:Data Validation Middleware
Validate data before applying changes:Data Transformation Middleware
Transform data before it’s applied:Debouncing Middleware
Debounce rapid data changes:Conditional Update Middleware
Prevent certain updates based on conditions:Sync with External Store Middleware
Synchronize state with an external store:Audit Trail Middleware
Track all changes for audit purposes:Field-Specific Middleware
Apply logic to specific fields:Composing Multiple Middleware
Chain multiple middleware functions:Error Handling in Middleware
Handle errors gracefully:Performance Considerations
Middleware runs on every state change. Keep it performant:Testing Middleware
Test your middleware in isolation:Best Practices
- Keep middleware pure: Avoid side effects when possible
- Call defaultReducer: Always call the default reducer unless intentionally preventing the update
- Handle errors: Wrap middleware logic in try-catch blocks
- Consider performance: Avoid expensive operations on every state change
- Return consistent state: Ensure the returned state structure is valid
- Document behavior: Clearly document what your middleware does
- Test thoroughly: Test middleware with various actions and states
- Compose carefully: When composing middleware, consider the execution order
- Avoid mutation: Don’t mutate the state object; create new objects
- Use TypeScript: Leverage type safety for better reliability
Common Use Cases
- Analytics: Track user interactions and form completion
- Auto-save: Automatically save form data to a backend
- Validation: Add custom validation beyond JSON Schema
- Formatting: Auto-format fields as users type
- Calculations: Compute derived values based on other fields
- Permissions: Control who can edit which fields
- Versioning: Track different versions of form data
- Undo/Redo: Implement undo/redo functionality
- Cross-field validation: Validate relationships between fields
- External sync: Keep form data in sync with external systems