javagraphql

How can I pass a variable to a GraphQL request in Java


I am invoking a GraphQL endpoint with the following Java code snippet.

    public void scheduleOrdAggregation(){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        String query = "mutation {\n" +
                "    result: scheduleOpenResourceDiscoveryAggregation(\n" +
                "        applicationID: $applicationId\n" +
                "    )\n" +
                "    {\n" +
                "        operationId\n" +
                "    }\n" +
                "}";
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("query", query);
        Map<String, Object> variables = new HashMap<>();
        variables.put("applicationId", "e3be7c76-9852-4f10-afc3-ca6da082e813");
        requestBody.put("variables", variables);
        //requestBody.put("variable_values", Collections.singletonMap("applicationId", "e3be7c76-9852-4f10-afc3-ca6da082e813"));

        HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
        ResponseEntity<String> response = restTemplateForUcl.postForEntity(uclEndpoint, entity, String.class);
    }

However I get an error saying

422 Unprocessable Entity: "{"errors":[{"message":"Internal Server Error [errorID=920abef1-2ad2-4238-90b7-9552f49d428f, reason: input:3: Variable \"$applicationId\" is not defined.]","extensions":{"error":"InternalError","error_code":10}}],"data":null}"

Is there a mistake in my syntax here? If I hardcode the field applicationID instead of a variable it works fine.

I am not using Spring Graph QL yet but was wondering if that is the way to go?

Thanks for the inputs. Prabal


Solution

  • I don't know if this is the only issue, since I've never written GraphQL requests without library support, but when breaking down your mutation, it currently looks like this:

    mutation {
        result: scheduleOpenResourceDiscoveryAggregation(
            applicationID: $applicationId
        ) {
            operationId
        }
    }
    

    In the mutation, you're using a variable $applicationId. It looks like there's a missing variable declaration here. It should look more like this:

    mutation($applicationId: ID!) {
        result: scheduleOpenResourceDiscoveryAggregation(
            applicationID: $applicationId
        ) {
            operationId
        }
    }
    

    However, if you're using GraphQL frequently in your service(s), leveraging this framework can save you a lot of time and reduce the chance of errors compared to manually writing code each time. spring-for-graphql comes with a lot of useful classes, such as a GraphQL client, which can make writing requests much easier. For example, you could do something like this:

    class TasklistAdapter(
        private val client: HttpGraphQlClient
    ) : TasklistApi {
    
        ...
    
        override fun sendCompleteUserTaskCommand(userTaskId: String, data: Map<String, Any>): Boolean {
            val result = client.document(completeUserTask)
                .variable("id", userTaskId)
                .variable("data", data)
                .execute()
                .block()
    
            ...
        }
    }