Fix CapabilityStatement conformance for resources without interactions#5473
Conversation
…icrosoft#5394) In STU3, CapabilityStatement.rest.resource.interaction has min cardinality 1. Resources like Parameters that are explicitly excluded from interaction population were still appearing in the resource list, causing FHIR-conformant parsers (e.g. Firely SDK 6.x) to reject the CapabilityStatement with a cardinality error. Remove resources with empty interaction lists in Build() before serialization.
There was a problem hiding this comment.
Pull request overview
Updates the conformance metadata generation to avoid emitting CapabilityStatement.rest.resource entries that have zero interactions, addressing STU3’s minimum cardinality requirement and preventing strict FHIR parsers from rejecting /metadata.
Changes:
- Adds a cleanup pass in
CapabilityStatementBuilder.Build()to remove resource components with an emptyinteractioncollection. - Documents the STU3 cardinality rationale inline to clarify why resources like
Parametersmust be excluded when they have no interactions.
| // so resources without interactions (e.g. Parameters) must be excluded. | ||
| foreach (var restComponent in _statement.Rest) | ||
| { | ||
| restComponent.Resource.RemoveWhere(r => r.Interaction == null || r.Interaction.Count == 0); |
There was a problem hiding this comment.
restComponent.Resource is typed as ICollection<ListedResourceComponent> (see ListedRestComponent.Resource), so RemoveWhere(...) is not available and this won’t compile. Consider removing via ICollection.Remove (e.g., collect matching items first) or casting to HashSet<ListedResourceComponent> before calling RemoveWhere.
| restComponent.Resource.RemoveWhere(r => r.Interaction == null || r.Interaction.Count == 0); | |
| var resourcesToRemove = restComponent.Resource | |
| .Where(r => r.Interaction == null || r.Interaction.Count == 0) | |
| .ToList(); | |
| foreach (var resource in resourcesToRemove) | |
| { | |
| restComponent.Resource.Remove(resource); | |
| } |
| // Remove resource entries with no interactions to ensure FHIR conformance. | ||
| // In STU3, CapabilityStatement.rest.resource.interaction has min cardinality 1, | ||
| // so resources without interactions (e.g. Parameters) must be excluded. | ||
| foreach (var restComponent in _statement.Rest) | ||
| { | ||
| restComponent.Resource.RemoveWhere(r => r.Interaction == null || r.Interaction.Count == 0); | ||
| } |
There was a problem hiding this comment.
This change addresses a STU3 conformance edge case; please add/extend a unit test that exercises the typical builder pipeline (e.g., PopulateDefaultResourceInteractions() followed by SyncSearchParameters()) and asserts no CapabilityStatement.rest.resource entries are emitted with an empty interaction collection (specifically that Parameters is absent in STU3). This will prevent regressions if future code paths create resources without interactions.
|
Hi team! This PR needs the required metadata labels to pass CI. Could a maintainer please add:
Thank you! |
Copilot correctly noted that Resource is typed as ICollection, not HashSet, so RemoveWhere is unavailable. Use Where + ToList + Remove which works on any ICollection.
|
Addressed Copilot's review:
|
Summary
Fixes #5394.
In STU3,
CapabilityStatement.rest.resource.interactionhas a minimum cardinality of 1 (spec). Resources likeParametersthat are explicitly excluded from interaction population (line 303-307) were still appearing in the resource list with an empty interaction array, causing FHIR-conformant parsers (e.g., Firely SDK 6.x with strict validation) to reject the CapabilityStatement.Changes
CapabilityStatementBuilder.Build(), added a cleanup step that removes resource entries with no interactions before serializationWhy this approach
Rather than modifying how
Parametersis handled specifically, this cleanup catches any resource that ends up with zero interactions — making it robust against future edge cases. The comment explains the STU3 cardinality requirement for maintainability.Test plan
/metadatareturns a valid CapabilityStatement parseable by Firely SDK 6.xParametersno longer appears inCapabilityStatement.rest.resourcewhen it has no interactionsAs a certified HL7 FHIR Implementer, I'm excited to contribute to the FHIR server. I'm also working on FHIRBridge, an open-source FHIR integration toolkit — happy to collaborate on interoperability improvements.