Implement comprehensive compound document validation for JSON:API#24
Implement comprehensive compound document validation for JSON:API#24
Conversation
Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
|
@copilot Take a screenshot showing the change in relation to the validator UI |
Here's a screenshot showing the new compound document validation features in action. The validator now includes four new validation tests (highlighted in green):
The screenshot shows a successful validation of a compound document with 89 tests passed, including the new compound document validations testing an endpoint with |
There was a problem hiding this comment.
Pull Request Overview
This PR implements comprehensive compound document validation for JSON:API v1.1 specification, adding critical validation rules for included resources and their relationships with primary data.
- Validates that
includedmember only appears whendatamember exists - Implements resource linkage validation to detect orphaned included resources
- Adds duplicate resource detection in included arrays
|
|
||
| return { | ||
| total: totalRelationships, | ||
| bidirectional: Math.floor(bidirectionalCount / 2) // Each bidirectional pair is counted twice |
There was a problem hiding this comment.
The bidirectional count calculation is incorrect. The current logic counts each relationship individually but then divides by 2, which doesn't properly identify bidirectional pairs. A bidirectional relationship should only be counted once when both A->B and B->A exist.
| // Check if reverse relationship exists | ||
| if (relationships.has(reverseRelationshipPair)) { | ||
| bidirectionalCount++ | ||
| } |
There was a problem hiding this comment.
This logic will count each bidirectional relationship twice (once for each direction), but the division by 2 at line 854 assumes this double-counting. However, the increment happens for every relationship that has a reverse, not just when discovering a bidirectional pair for the first time.
| const orphanedResources = [] | ||
| includedResources.forEach(resourceKey => { | ||
| if (!referencedResources.has(resourceKey)) { | ||
| const [type, id] = resourceKey.split(':') |
There was a problem hiding this comment.
The split(':') operation is unsafe if resource IDs contain colons. Since JSON:API allows any string as an ID, this could incorrectly parse resource keys like 'user:admin:123' where the ID is 'admin:123'.
| const missingResources = [] | ||
| referencedResources.forEach(resourceKey => { | ||
| if (!includedResources.has(resourceKey)) { | ||
| const [type, id] = resourceKey.split(':') |
There was a problem hiding this comment.
The split(':') operation is unsafe if resource IDs contain colons. Since JSON:API allows any string as an ID, this could incorrectly parse resource keys like 'user:admin:123' where the ID is 'admin:123'.

This PR implements complete compound document validation for JSON:API v1.1 specification compliance, addressing all the validation gaps identified in the issue.
Changes Made
The implementation adds comprehensive validation for compound documents through new validation functions in
DocumentValidator.js:1. Included/Data Member Pairing
Validates that
includedmember is only present whendatamember exists:2. Resource Linkage Validation
Ensures all included resources are actually referenced from primary data relationships:
3. Duplicate Resource Detection
Identifies duplicate resources in the included array by
type:id:4. Edge Case Handling
Properly handles scenarios like
data: nullwith included resources:Key Features
Testing
All validation scenarios have been thoroughly tested:
The implementation provides clear reporting for compound document issues while maintaining compatibility with existing JSON:API validation functionality.
Fixes #9.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.