fix(jsonapi): default Resource relationships to serde_json::Value#86
Merged
shadowhand merged 1 commit intorefactor-extract-domain-modulefrom Apr 28, 2026
Merged
Conversation
The generic `Resource<A, R = ()>` introduced in #77 silently regressed deserialization: the previous hand-rolled `*Resource` types had no `relationships` field at all, so serde skipped it; the new generic declares it explicitly as `R` and defaults `R` to `()`, which only deserializes from null or absent. Real JSON:API responses for clinicians, teams, and others carry populated relationships objects (e.g. `{"team": {"data": {...}}}`). Against the live API those calls would have failed at runtime with `invalid type: map, expected unit`. Test mocks all omitted the relationships key, so the regression slipped through CI. Switching the default to `serde_json::Value` accepts any JSON shape on the field — null, object, array, primitive, or absent — and callers that don't read it can ignore it. Callers that need typed relationships still pass an explicit `R` (see test_typed_relationships and the existing call sites for `prepare`'s WorkspaceAttrs etc., which use named structs and are unaffected). Adds three regression tests covering null, empty object, and populated object cases — the third would have caught this had it been there. Spotted by Devin AI in review of #78.
shadowhand
added a commit
that referenced
this pull request
Apr 28, 2026
…fault fix(jsonapi): default Resource relationships to serde_json::Value
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a JSON:API deserialization regression introduced in #77 and surfaced in code review on #78.
The bug
Resource<A, R = ()>was added in #77 as a generic envelope. The previous hand-rolled*Resourcetypes (TeamResource,ClinicianResource, etc.) had norelationshipsfield at all, so serde silently skipped the key. The new generic declares the field explicitly withRdefaulting to(), which only deserializes fromnullor an absent key.Real JSON:API responses for clinicians, teams, etc. carry populated relationships objects (e.g.
{"team": {"data": {...}}}). Against the live API those calls would have failed at runtime withinvalid type: map, expected unit. Every test mock omittedrelationships, so the regression slipped through CI.Reproduced locally:
relationshipsfieldR = ()(before)R = serde_json::Value(after)null{}The fix
Switch the default in
src/jsonapi.rsfromR = ()toR = serde_json::Value.Valueaccepts any JSON shape andDefault::default()returnsValue::Null. Callers that don't read.relationshipsare unaffected; callers that do (the typed-relationships path intest_typed_relationships) are unaffected since they pass an explicitR.Test additions
Three regression tests covering null, empty-object, and populated-object cases. The third would have caught this in #77 had it been there. Test count: 291 → 294 (276 lib + 7 bin + 11 integration).
Spotted by
Devin AI's review on #78.
Test plan
cargo fmt --checkcleancargo clippy --all-targets --all-features -- -D warningscleancargo test— 294 passhttps://claude.ai/code/session_012fVDyKBysF1ERtvVuEAw2Y
Generated by Claude Code