diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_0_0/5276-the-graphql-request-results-in-an-http-400-error.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_0_0/5276-the-graphql-request-results-in-an-http-400-error.yaml new file mode 100644 index 00000000000..389409cd931 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_0_0/5276-the-graphql-request-results-in-an-http-400-error.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 5276 +title: "Previously, GraphQL queries will error when using base resource search parameters such as '_id' after search parameter rebuild. +This has been fixed." diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/GraphQLR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/GraphQLR4Test.java index a4395fb244f..5c458052cd2 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/GraphQLR4Test.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/GraphQLR4Test.java @@ -237,6 +237,31 @@ public class GraphQLR4Test extends BaseResourceProviderR4Test { myCaptureQueriesListener.logSelectQueries(); } + @Test + public void testId_Search_Patient() throws IOException { + initTestPatients(); + + String query = "{PatientList(_id: " + myPatientId0.getIdPart() + ") {id}}"; + HttpGet httpGet = new HttpGet(myServerBase + "/$graphql?query=" + UrlUtil.escapeUrlParam(query)); + + try (CloseableHttpResponse response = ourHttpClient.execute(httpGet)) { + String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); + ourLog.info(resp); + + @Language("json") + String expected = """ + { + "PatientList":[{ + "id":" """ + myPatientId0 + """ + /_history/1" + }] + }"""; + assertEquals(TestUtil.stripWhitespace(DATA_PREFIX + + expected + + DATA_SUFFIX), TestUtil.stripWhitespace(resp)); + } + } + private void initTestPatients() { Patient p = new Patient(); p.addName() diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java index 3518530bbcf..d37ed620067 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/util/ISearchParamRegistry.java @@ -131,4 +131,21 @@ public interface ISearchParamRegistry { } return availableSearchParamDef; } + + /** + * Get all the search params for a resource. First, check the resource itself, then check the top-level `Resource` resource and combine the two. + * + * @param theResourceType the resource type. + * + * @return the {@link ResourceSearchParams} that has all the search params. + */ + default ResourceSearchParams getRuntimeSearchParams(String theResourceType) { + ResourceSearchParams availableSearchParams = + getActiveSearchParams(theResourceType).makeCopy(); + ResourceSearchParams resourceSearchParams = getActiveSearchParams("Resource"); + resourceSearchParams + .getSearchParamNames() + .forEach(param -> availableSearchParams.addSearchParamIfAbsent(param, resourceSearchParams.get(param))); + return availableSearchParams; + } } diff --git a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/graphql/DaoRegistryGraphQLStorageServices.java b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/graphql/DaoRegistryGraphQLStorageServices.java index 529aef2a592..7a93834ef3e 100644 --- a/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/graphql/DaoRegistryGraphQLStorageServices.java +++ b/hapi-fhir-storage/src/main/java/ca/uhn/fhir/jpa/graphql/DaoRegistryGraphQLStorageServices.java @@ -130,7 +130,7 @@ public class DaoRegistryGraphQLStorageServices implements IGraphQLStorageService RuntimeResourceDefinition typeDef = fhirContext.getResourceDefinition(theType); SearchParameterMap params = new SearchParameterMap(); - ResourceSearchParams searchParams = mySearchParamRegistry.getActiveSearchParams(typeDef.getName()); + ResourceSearchParams searchParams = mySearchParamRegistry.getRuntimeSearchParams(typeDef.getName()); for (Argument nextArgument : resourceSearchParam) {