hapifhir / hapi-fhir

🔥 HAPI FHIR - Java API for HL7 FHIR Clients and Servers
http://hapifhir.io
Apache License 2.0
1.98k stars 1.3k forks source link

JSON parser can encode resources that it cannot later parse #5106

Open russgray opened 1 year ago

russgray commented 1 year ago

Describe the bug Given a resource with an extension that contains both a value and a subextension, JsonParser can encode it to a string with no error ~(resulting in a valid fhir resource that will be accepted by our fhir store)~ resulting in invalid fhir json that cannot subsequently be parsed.

To Reproduce

The following test will not run to completion. It throws in the parseResource call with message ca.uhn.fhir.parser.DataFormatException: HAPI-1811: Extension (URL='http://fhir.patientsknowbest.com/structuredefinition/test') must not have both a value and other contained extensions

This restriction seems unique to the parsing method; encodeResourceToString has no such constraint.

@Test
void testHapiSerializeThenDeserializeNestedExtension() {

    // GIVEN - extension with value and subextension
    Extension rootExtension = new Extension()
            .setUrl("http://fhir.patientsknowbest.com/structuredefinition/test")
            .setValue(new StringType("456"));
    rootExtension.addExtension(new Extension().setValue(new StringType("123")));

    Patient patientResource = new Patient();
    patientResource.addExtension(rootExtension);

    IParser parser = FhirContext.forR4().newJsonParser();

    // WHEN - resource is serialized and the deserialized
    String json = parser.encodeResourceToString(patientResource);
    Patient actual = parser.parseResource(Patient.class, json);

    // THEN - resource is restored
    assertTrue(actual.equalsDeep(patientResource));
}

Expected behavior HAPI should ~be able to parse any valid fhir json, especially where it was the generator of that json initially~ not generate invalid fhir json.

Screenshots If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

Additional context Add any other context about the problem here.

grahamegrieve commented 1 year ago

This is not valid json. An extension cannot contain both a value and a sub-extension (spec says "An extension SHALL have either a value (i.e. a value[x] element) or sub-extensions, but not both.")

russgray commented 1 year ago

Should encodeResourceToString not reject it, in that case? Or even the object builder API? Our concern is that we are able to successfully build resources that cannot be later parsed. If we had a failure during object construction or encoding, it would also mitigate that.