Skip to content

feat(core): validate resource update requests - #34

Merged
kazemek merged 5 commits into
mainfrom
feat/update-request-validation
Aug 2, 2026
Merged

kazemek merged 5 commits into
mainfrom
feat/update-request-validation

Conversation

@kazemek

@kazemek kazemek commented Aug 2, 2026 •

Copy link
Copy Markdown
Collaborator

Refine the milestone into an implementation-ready contract covering
endpoint-identity context, stable rule codes, primary-scoped update
rules, and both plan-review rounds.

Add UPDATE_REQUEST document usage with primary-single-resource shape,
relationship replacement-data, and optional expected endpoint identity
checks (EndpointIdentity on ValidationContext), scoped to the primary
resource so included resources keep response semantics.

Summary by CodeRabbit

  • New Features

    • Added JSON:API update-request validation.
    • Update requests require a single primary resource with an ID.
    • Added optional endpoint type and ID matching.
    • Added relationship data validation for supplied relationships.
    • Added new validation rule codes and update-request usage guidance.
  • Documentation

    • Updated conformance checklists, milestone documentation, package guidance, and usage examples.
  • Tests

    • Added comprehensive coverage for valid and invalid update requests, endpoint matching, relationships, included resources, and existing validation behavior.

kazemek added 2 commits August 2, 2026 22:57
Refine the milestone into an implementation-ready contract covering
endpoint-identity context, stable rule codes, primary-scoped update
rules, and both plan-review rounds.
Add UPDATE_REQUEST document usage with primary-single-resource shape,
relationship replacement-data, and optional expected endpoint identity
checks (EndpointIdentity on ValidationContext), scoped to the primary
resource so included resources keep response semantics.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3c71cff9-f3e8-41e0-b090-957f1764ff37

📥 Commits

Reviewing files that changed from the base of the PR and between c2572b9 and d713569.

📒 Files selected for processing (5)
  • .agentWork/milestones/phase-1-3-update-request-validation.md
  • docs/conformance.md
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidator.java
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/package-info.java
  • jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/UpdateRequestValidationSpec.groovy
🚧 Files skipped from review as they are similar to previous changes (4)
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/package-info.java
  • docs/conformance.md
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidator.java
  • jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/UpdateRequestValidationSpec.groovy

📝 Walkthrough

Walkthrough

Phase 1.3 adds JSON:API update-request validation. The change adds endpoint identity support, update-specific rule codes, primary-resource and relationship checks, focused tests, and documentation.

Changes

Update request validation

Layer / File(s) Summary
Validation contracts and context
jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/*
Adds DocumentUsage.UPDATE_REQUEST, EndpointIdentity, nullable endpoint identity context support, and three validation rule codes.
Update-request validator rules
jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidator.java
Requires one primary resource, requires relationship data, and checks the resource type and ID against the configured endpoint identity.
Focused update validation coverage
jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/UpdateRequestValidationSpec.groovy
Tests primary data, identifiers, relationships, attributes, endpoint identity, included resources, extensions, and existing create/response behavior.
Documentation and context migration
.agentWork/milestones/*, docs/conformance.md, jsonapi-java-core/README.md, jsonapi-java-*/src/test/*, jsonapi-java-test-fixtures/*
Documents Phase 1.3 and updates existing ValidationContext construction sites for the new component.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant ValidationContext
  participant JsonApiDocumentValidator
  participant ValidationErrors
  Caller->>ValidationContext: configure UPDATE_REQUEST
  Caller->>ValidationContext: set expected EndpointIdentity
  Caller->>JsonApiDocumentValidator: validate document
  JsonApiDocumentValidator->>ValidationContext: read update settings
  JsonApiDocumentValidator->>JsonApiDocumentValidator: validate primary resource and relationships
  JsonApiDocumentValidator->>ValidationErrors: report rule codes and JSON pointers
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding core validation for resource update requests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/update-request-validation

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/package-info.java (1)

9-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Scope the relationship requirement to the primary resource.

The validator applies the data requirement only to relationships of the primary resource. Included resources keep response semantics. State that scope here so readers do not expect the rule on included resources.

📝 Proposed wording
- * single-resource primary data, replacement {`@code` data} on every supplied relationship, and — when
+ * single-resource primary data, replacement {`@code` data} on every relationship supplied by the
+ * primary resource, and — when
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/package-info.java`
around lines 9 - 13, Update the UPDATE_REQUEST documentation in
package-info.java to clarify that the replacement data requirement applies only
to relationships of the primary resource; explicitly preserve response semantics
for included resources.
jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/UpdateRequestValidationSpec.groovy (1)

282-293: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a test for endpoint identity preservation across the with* methods.

Every call here applies withExpectedEndpointIdentity last. ValidationContext.withDocumentUsage, withLinksContext, and withSparseFieldsetException now copy expectedEndpointIdentity forward. If one of those copies were dropped, this suite would still pass.

💚 Proposed additional feature
+  def "expected endpoint identity survives context derivation"() {
+    given:
+    def base = ValidationContext.defaults()
+        .withExpectedEndpointIdentity(new EndpointIdentity("articles", "1"))
+
+    expect:
+    base.withDocumentUsage(DocumentUsage.UPDATE_REQUEST).expectedEndpointIdentity() ==
+        new EndpointIdentity("articles", "1")
+    base.withLinksContext(LinksContext.RESOURCE).expectedEndpointIdentity() ==
+        new EndpointIdentity("articles", "1")
+    base.withSparseFieldsetException(true).expectedEndpointIdentity() ==
+        new EndpointIdentity("articles", "1")
+  }

As per coding guidelines, "Add or update mirrored Spock tests for requested production behavior."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/UpdateRequestValidationSpec.groovy`
around lines 282 - 293, Extend the UpdateRequestValidationSpec coverage around
the existing matching endpoint identity test to apply withDocumentUsage,
withLinksContext, and withSparseFieldsetException after
withExpectedEndpointIdentity, then validate the document and assert no exception
is thrown. Ensure the test verifies expectedEndpointIdentity is preserved
through each with* method rather than setting it last.

Source: Coding guidelines

jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidator.java (1)

327-348: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Replace the path-string primary-scope test with an explicit parameter.

Both this method and validateResourceRelationships at line 157 detect the primary resource by comparing path to the "/data" literal. This couples an update-policy decision to pointer formatting. A future change to the primary pointer, or a new caller that passes an equivalent path, would silently disable the update rules. Pass a boolean primary flag from validatePrimaryData instead.

This is a maintainability improvement. Current behavior is correct because validatePrimaryData is the only caller that uses PATH_DATA, and update documents allow only single-resource primary data.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidator.java`
around lines 327 - 348, Replace path-based primary-resource detection in
validateUpdateEndpointIdentity and validateResourceRelationships with an
explicit boolean primary parameter. Update validatePrimaryData to pass true for
the primary resource and pass false for relationship resources or other callers,
then base the update-policy checks on that flag instead of comparing path with
PATH_DATA. Preserve the existing validation behavior for primary update data.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agentWork/milestones/phase-1-3-update-request-validation.md:
- Around line 232-254: Update the Phase 1.3 milestone document to mark the
milestone complete only when every listed acceptance criterion has supporting
evidence; otherwise keep it incomplete and record blockers for each unverified
test, build, Spotless, module-docs, or Sonar check. Then synchronize the
corresponding milestone status in the milestone index README.

In `@docs/conformance.md`:
- Line 68: Update the conformance checklist row for omitted/present/present-null
attributes and wrappers to distinguish absent or present-empty relationship
wrappers from explicit null values within Attributes. Clarify that attributes:
null and relationships: null are not implied as supported, while preserving the
documented no-normalization behavior.

---

Nitpick comments:
In
`@jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidator.java`:
- Around line 327-348: Replace path-based primary-resource detection in
validateUpdateEndpointIdentity and validateResourceRelationships with an
explicit boolean primary parameter. Update validatePrimaryData to pass true for
the primary resource and pass false for relationship resources or other callers,
then base the update-policy checks on that flag instead of comparing path with
PATH_DATA. Preserve the existing validation behavior for primary update data.

In
`@jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/package-info.java`:
- Around line 9-13: Update the UPDATE_REQUEST documentation in package-info.java
to clarify that the replacement data requirement applies only to relationships
of the primary resource; explicitly preserve response semantics for included
resources.

In
`@jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/UpdateRequestValidationSpec.groovy`:
- Around line 282-293: Extend the UpdateRequestValidationSpec coverage around
the existing matching endpoint identity test to apply withDocumentUsage,
withLinksContext, and withSparseFieldsetException after
withExpectedEndpointIdentity, then validate the document and assert no exception
is thrown. Ensure the test verifies expectedEndpointIdentity is preserved
through each with* method rather than setting it last.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f35c679a-5d88-4256-ac6c-5af7627ddeac

📥 Commits

Reviewing files that changed from the base of the PR and between 993e037 and c2572b9.

📒 Files selected for processing (15)
  • .agentWork/milestones/README.md
  • .agentWork/milestones/phase-1-3-update-request-validation.md
  • docs/conformance.md
  • jsonapi-java-core/README.md
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/DocumentUsage.java
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/EndpointIdentity.java
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidator.java
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/ValidationContext.java
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/ValidationRuleCode.java
  • jsonapi-java-core/src/main/java/io/github/kazemek/jsonapi/core/validation/package-info.java
  • jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/JsonApiDocumentValidatorSpec.groovy
  • jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/UpdateRequestValidationSpec.groovy
  • jsonapi-java-core/src/test/groovy/io/github/kazemek/jsonapi/core/validation/ValidatorCoverageSpec.groovy
  • jsonapi-java-jackson3/src/test/groovy/io/github/kazemek/jsonapi/jackson3/DocumentReaderSpec.groovy
  • jsonapi-java-test-fixtures/src/main/groovy/io/github/kazemek/jsonapi/testfixtures/writer/Models.groovy

Comment thread .agentWork/milestones/phase-1-3-update-request-validation.md Outdated
Comment thread docs/conformance.md Outdated
kazemek added 3 commits August 2, 2026 23:21
Thread a boolean primary flag from validatePrimaryData instead of comparing
the resource path against /data, so primary-scoped update rules cannot be
silently disabled by pointer-format changes.
Assert withDocumentUsage, withLinksContext, and withSparseFieldsetException
preserve the expected endpoint identity, so a dropped copy-forward is
caught.
Scope the update relationship-data wording to the primary resource, clarify
presence states in the conformance checklist, mark the milestone acceptance
criteria complete, and sync the milestone mechanism description to the
primary flag.
@kazemek

kazemek commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator Author

Review feedback addressed in three commits pushed to feat/update-request-validation:

  • 5598642 refactor(core): scope update rules by primary flag — replaced the PATH_DATA.equals(path) primary-resource detection in validateUpdateEndpointIdentity and validateResourceRelationships with an explicit boolean primary flag threaded from validatePrimaryData (true for the single primary resource, false for collection elements and included resources).
  • aa27773 test(core): cover endpoint identity context pass-through — added a test asserting withDocumentUsage, withLinksContext, and withSparseFieldsetException all preserve expectedEndpointIdentity, so a dropped copy-forward cannot pass the suite.
  • d713569 docs: address Phase 1.3 review feedback — scoped the package-info relationship-data wording to the primary resource (included resources keep response semantics), clarified the conformance presence-states row, and flipped the milestone acceptance criteria to [x] with status Complete (both inline threads replied separately).

All gates green on the final tree: focused spec, ./gradlew clean build, Spotless, and Sonar Quality Gate (0 new issues).

@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2026

Copy link
Copy Markdown

@kazemek
kazemek merged commit 9124951 into main Aug 2, 2026
3 checks passed
@kazemek
kazemek deleted the feat/update-request-validation branch August 2, 2026 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant