diff --git a/client/api/pom.xml b/client/api/pom.xml
index ba854cc10..7aa5acda1 100644
--- a/client/api/pom.xml
+++ b/client/api/pom.xml
@@ -40,8 +40,8 @@
- jakarta.json
- jakarta.json-api
+ com.fasterxml.jackson.core
+ jackson-databind
provided
diff --git a/client/api/src/main/java/io/smallrye/graphql/client/Request.java b/client/api/src/main/java/io/smallrye/graphql/client/Request.java
index 40c9f5331..027bf982c 100644
--- a/client/api/src/main/java/io/smallrye/graphql/client/Request.java
+++ b/client/api/src/main/java/io/smallrye/graphql/client/Request.java
@@ -2,7 +2,7 @@
import java.util.Map;
-import jakarta.json.JsonObject;
+import com.fasterxml.jackson.databind.node.ObjectNode;
public interface Request {
String getDocument();
@@ -23,6 +23,6 @@ public interface Request {
String toJson();
- JsonObject toJsonObject();
+ ObjectNode toJsonObject();
}
diff --git a/client/api/src/main/java/io/smallrye/graphql/client/Response.java b/client/api/src/main/java/io/smallrye/graphql/client/Response.java
index beef05cd6..b77b41ded 100644
--- a/client/api/src/main/java/io/smallrye/graphql/client/Response.java
+++ b/client/api/src/main/java/io/smallrye/graphql/client/Response.java
@@ -3,17 +3,15 @@
import java.util.List;
import java.util.Map;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonValue;
+import com.fasterxml.jackson.databind.node.ObjectNode;
public interface Response {
/**
* The 'data' object contained in the response.
- * Can be JsonValue.NULL if the response contains an empty field, or `null` if the response
- * does not contain this field at all.
+ * Can be null if the response does not contain this field at all or contains a null value.
*/
- JsonObject getData();
+ ObjectNode getData();
/**
* List of errors contained in this response.
@@ -23,7 +21,7 @@ public interface Response {
/**
* List of user-made extensions contained in this response.
*/
- JsonObject getExtensions();
+ ObjectNode getExtensions();
/**
* Transform the contents of the `rootField` from this response into a list of objects
diff --git a/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java b/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java
index 63f8c0322..81b594ee9 100644
--- a/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java
+++ b/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java
@@ -7,13 +7,13 @@
import java.util.Map;
import java.util.Objects;
-import jakarta.json.JsonObject;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import io.smallrye.graphql.client.GraphQLError;
public final class TypesafeResponse extends ErrorOr {
private Map> transportMeta;
- private JsonObject extensions;
+ private ObjectNode extensions;
public static TypesafeResponse of(T value) {
return new TypesafeResponse<>(value, null);
@@ -33,7 +33,7 @@ private TypesafeResponse(T value, List errors) {
private TypesafeResponse(TypesafeResponse typesafeResponse,
Map> transportMeta,
- JsonObject extensions) {
+ ObjectNode extensions) {
super(
(typesafeResponse.isPresent()) ? typesafeResponse.get() : null,
(typesafeResponse.hasErrors()) ? typesafeResponse.getErrors() : null);
@@ -43,7 +43,7 @@ private TypesafeResponse(TypesafeResponse typesafeResponse,
public static TypesafeResponse withTransportMetaAndExtensions(TypesafeResponse typesafeResponse,
Map> transportMeta,
- JsonObject responseExtensions) {
+ ObjectNode responseExtensions) {
return new TypesafeResponse(typesafeResponse, transportMeta, responseExtensions);
}
@@ -56,9 +56,9 @@ public Map> getTransportMeta() {
}
/**
- * Returns a JsonObject containing extensions to the GraphQL response, if any.
+ * Returns an ObjectNode containing extensions to the GraphQL response, if any.
*/
- public JsonObject getExtensions() {
+ public ObjectNode getExtensions() {
return extensions;
}
diff --git a/client/implementation-vertx/pom.xml b/client/implementation-vertx/pom.xml
index a1787e477..578134ba7 100644
--- a/client/implementation-vertx/pom.xml
+++ b/client/implementation-vertx/pom.xml
@@ -29,12 +29,16 @@
microprofile-config-api
- jakarta.json
- jakarta.json-api
+ com.fasterxml.jackson.core
+ jackson-databind
- jakarta.json.bind
- jakarta.json.bind-api
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ io.smallrye
+ smallrye-graphql-jackson-jsonb-compat
@@ -46,11 +50,6 @@
io.vertx
vertx-web-client
-
- org.eclipse
- yasson
- runtime
-
io.smallrye
diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java
index e7c1cd905..5a6e6f5a9 100644
--- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java
+++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java
@@ -11,10 +11,10 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
-import jakarta.json.JsonObject;
-
import org.jboss.logging.Logger;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import io.smallrye.graphql.client.Request;
import io.smallrye.graphql.client.Response;
import io.smallrye.graphql.client.core.Document;
@@ -207,7 +207,7 @@ public Response executeSync(String query, Map variables, String
return executeSync(buildRequest(query, variables, operationName).toJsonObject(), headers);
}
- private Response executeSync(JsonObject json, MultiMap additionalHeaders) {
+ private Response executeSync(ObjectNode json, MultiMap additionalHeaders) {
if (executeSingleOperationsOverWebsocket) {
return executeSingleResultOperationOverWebsocket(json).await().indefinitely();
} else {
@@ -314,7 +314,7 @@ public Uni executeAsync(String query, Map variables, S
return executeAsync(buildRequest(query, variables, operationName).toJsonObject(), headers);
}
- private Uni executeAsync(JsonObject json, MultiMap additionalHeaders) {
+ private Uni executeAsync(ObjectNode json, MultiMap additionalHeaders) {
if (executeSingleOperationsOverWebsocket) {
return executeSingleResultOperationOverWebsocket(json);
} else {
@@ -384,7 +384,7 @@ public Multi subscription(String query, Map variables,
return subscription0(buildRequest(query, variables, operationName).toJsonObject());
}
- private Multi subscription0(JsonObject json) {
+ private Multi subscription0(ObjectNode json) {
return executeSubscriptionOverWebsocket(json);
}
@@ -447,7 +447,7 @@ private Uni webSocketHandler() {
});
}
- private Uni> executeSingleResultOperationOverHttp(JsonObject json, MultiMap allHeaders) {
+ private Uni> executeSingleResultOperationOverHttp(ObjectNode json, MultiMap allHeaders) {
return url.get()
.chain(instanceUrl -> Uni.createFrom().completionStage(
webClient.postAbs(instanceUrl)
@@ -461,7 +461,7 @@ private Response toResponse(HttpResponse httpResponse) {
allowUnexpectedResponseFields);
}
- private Uni executeSingleResultOperationOverWebsocket(JsonObject json) {
+ private Uni executeSingleResultOperationOverWebsocket(ObjectNode json) {
AtomicReference operationId = new AtomicReference<>();
AtomicReference handlerRef = new AtomicReference<>();
Uni rawUni = Uni.createFrom().emitter(rawEmitter -> {
@@ -483,7 +483,7 @@ private Uni executeSingleResultOperationOverWebsocket(JsonObject json)
.onItem().transform(data -> ResponseReader.readFrom(data, Collections.emptyMap()));
}
- private Multi executeSubscriptionOverWebsocket(JsonObject json) {
+ private Multi executeSubscriptionOverWebsocket(ObjectNode json) {
AtomicReference operationId = new AtomicReference<>();
AtomicReference handlerRef = new AtomicReference<>();
Multi rawMulti = Multi.createFrom().emitter(rawEmitter -> {
diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java
index 635e74298..2c6921e10 100644
--- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java
+++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java
@@ -1,6 +1,5 @@
package io.smallrye.graphql.client.vertx.typesafe;
-import static io.smallrye.graphql.client.impl.JsonProviderHolder.JSON_PROVIDER;
import static java.util.stream.Collectors.*;
import java.lang.reflect.Array;
@@ -23,16 +22,16 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
-import jakarta.json.JsonArray;
-import jakarta.json.JsonArrayBuilder;
-import jakarta.json.JsonBuilderFactory;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonObjectBuilder;
-import jakarta.json.JsonValue;
-
import org.jboss.logging.Logger;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import io.smallrye.graphql.client.InvalidResponseException;
+import io.smallrye.graphql.client.impl.RequestImpl;
import io.smallrye.graphql.client.impl.discovery.ServiceURLSupplier;
import io.smallrye.graphql.client.impl.discovery.StaticURLSupplier;
import io.smallrye.graphql.client.impl.discovery.StorkServiceURLSupplier;
@@ -61,7 +60,8 @@ class VertxTypesafeGraphQLClientProxy {
private static final Logger log = Logger.getLogger(VertxTypesafeGraphQLClientProxy.class);
- private static final JsonBuilderFactory jsonObjectFactory = JSON_PROVIDER.createBuilderFactory(null);
+ private static final ObjectMapper MAPPER = RequestImpl.MAPPER;
+ private static final JsonNodeFactory NODES = JsonNodeFactory.instance;
private final ConcurrentMap queryCache = new ConcurrentHashMap<>();
@@ -143,7 +143,7 @@ Object invoke(MethodInvocation method) {
MultiMap headers = MultiMap.caseInsensitiveMultiMap()
.addAll(new HeaderBuilder(api, method, additionalHeaders).build());
- JsonObject request = request(method);
+ ObjectNode request = request(method);
if (method.getReturnType().isUni()) {
if (executeSingleOperationsOverWebsocket) {
@@ -162,7 +162,7 @@ Object invoke(MethodInvocation method) {
}
}
- private Object executeSingleResultOperationOverHttpSync(MethodInvocation method, JsonObject request, MultiMap headers) {
+ private Object executeSingleResultOperationOverHttpSync(MethodInvocation method, ObjectNode request, MultiMap headers) {
MultiMap allHeaders = MultiMap.caseInsensitiveMultiMap();
allHeaders.addAll(headers);
// obtain values of dynamic headers and add them to the request
@@ -178,7 +178,7 @@ private Object executeSingleResultOperationOverHttpSync(MethodInvocation method,
allowUnexpectedResponseFields).read();
}
- private Uni
- jakarta.json
- jakarta.json-api
- provided
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ io.smallrye
+ smallrye-graphql-jackson-jsonb-compat
jakarta.json.bind
@@ -135,10 +146,5 @@
${version.mockito}
test
-
- org.eclipse
- yasson
- test
-
diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/JsonProviderHolder.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/JsonProviderHolder.java
deleted file mode 100644
index ea4a041da..000000000
--- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/JsonProviderHolder.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package io.smallrye.graphql.client.impl;
-
-import jakarta.json.spi.JsonProvider;
-
-// A central place to get the JsonProvider to avoid calling `JsonProvider.provider()` many times
-// due to associated performance costs.
-public class JsonProviderHolder {
-
- public static final JsonProvider JSON_PROVIDER = JsonProvider.provider();
-
-}
diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java
index 558d2523a..3ad4003c7 100644
--- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java
+++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java
@@ -1,24 +1,24 @@
package io.smallrye.graphql.client.impl;
-import static io.smallrye.graphql.client.impl.JsonProviderHolder.JSON_PROVIDER;
-
-import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
-import jakarta.json.JsonBuilderFactory;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonObjectBuilder;
-import jakarta.json.JsonValue;
-import jakarta.json.bind.Jsonb;
-import jakarta.json.bind.JsonbBuilder;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.json.JsonMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import io.smallrye.graphql.client.Request;
+import io.smallrye.graphql.jackson.jsonb.JsonbCompatModule;
public class RequestImpl implements Request {
- private static final JsonBuilderFactory JSON = JSON_PROVIDER.createBuilderFactory(null);
- private static final Jsonb JSONB = JsonbBuilder.create();
+ public static final ObjectMapper MAPPER = JsonMapper.builder()
+ .addModule(new JsonbCompatModule())
+ .enable(com.fasterxml.jackson.databind.DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)
+ .disable(com.fasterxml.jackson.databind.cfg.JsonNodeFeature.STRIP_TRAILING_BIGDECIMAL_ZEROES)
+ .build();
private final String document;
private Map variables;
@@ -76,64 +76,41 @@ public RequestImpl build() {
@Override
public String toJson() {
- JsonObjectBuilder queryBuilder = JSON.createObjectBuilder().add("query", document);
- if (!variables.isEmpty()) {
- queryBuilder.add("variables", _formatJsonVariables());
- }
- if (operationName != null && !operationName.isEmpty()) {
- queryBuilder.add("operationName", operationName);
- }
- if (extensions != null && !extensions.isEmpty()) {
- queryBuilder.add("extensions", _formatJsonMap(extensions));
+ try {
+ return MAPPER.writeValueAsString(toJsonObject());
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException("Failed to serialize request to JSON", e);
}
- return queryBuilder.build().toString();
}
@Override
- public JsonObject toJsonObject() {
- JsonObjectBuilder queryBuilder = JSON.createObjectBuilder().add("query", document);
+ public ObjectNode toJsonObject() {
+ ObjectNode node = MAPPER.createObjectNode();
+ node.put("query", document);
if (!variables.isEmpty()) {
- queryBuilder.add("variables", _formatJsonVariables());
+ node.set("variables", _formatJsonMap(variables));
}
if (operationName != null && !operationName.isEmpty()) {
- queryBuilder.add("operationName", operationName);
+ node.put("operationName", operationName);
}
if (extensions != null && !extensions.isEmpty()) {
- queryBuilder.add("extensions", _formatJsonMap(extensions));
+ node.set("extensions", _formatJsonMap(extensions));
}
- return queryBuilder.build();
- }
-
- private JsonObject _formatJsonVariables() {
- return _formatJsonMap(variables);
+ return node;
}
- private static JsonObject _formatJsonMap(Map map) {
- JsonObjectBuilder builder = JSON.createObjectBuilder();
-
+ private ObjectNode _formatJsonMap(Map map) {
+ ObjectNode node = MAPPER.createObjectNode();
map.forEach((k, v) -> {
- if (v instanceof String) {
- builder.add(k, (String) v);
- } else if (v instanceof Integer) {
- builder.add(k, (Integer) v);
- } else if (v instanceof JsonValue) {
- builder.add(k, (JsonValue) v);
- } else if (v instanceof Boolean) {
- builder.add(k, (Boolean) v);
- } else if (v instanceof Long) {
- builder.add(k, (Long) v);
- } else if (v instanceof Double) {
- builder.add(k, (Double) v);
- } else if (v instanceof Enum>) {
- builder.add(k, ((Enum>) v).name());
- } else if (v == null) {
- builder.addNull(k);
+ if (v == null) {
+ node.putNull(k);
+ } else if (v instanceof JsonNode) {
+ node.set(k, (JsonNode) v);
} else {
- builder.add(k, JSON_PROVIDER.createReader(new StringReader(JSONB.toJson(v))).read());
+ node.set(k, MAPPER.valueToTree(v));
}
});
-
- return builder.build();
+ return node;
}
@Override
diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java
index d17f95a53..b9b6bd0d8 100644
--- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java
+++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java
@@ -3,14 +3,14 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
-import jakarta.json.JsonArray;
-import jakarta.json.JsonNumber;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonString;
-import jakarta.json.JsonValue;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import io.smallrye.graphql.client.GraphQLClientException;
import io.smallrye.graphql.client.GraphQLError;
@@ -23,18 +23,18 @@ public class ResponseImpl implements Response {
public static final String STATUS_CODE = "";
public static final String STATUS_MESSAGE = "";
- private final JsonObject data;
+ private final ObjectNode data;
private final List errors;
- private final JsonObject extensions;
+ private final ObjectNode extensions;
private final Map> metadata;
- public ResponseImpl(JsonObject data, List errors, Map> headers) {
+ public ResponseImpl(ObjectNode data, List errors, Map> headers) {
this(data, errors, null, headers);
}
- public ResponseImpl(JsonObject data,
+ public ResponseImpl(ObjectNode data,
List errors,
- JsonObject extensions,
+ ObjectNode extensions,
Map> headers) {
this.data = data;
this.errors = errors;
@@ -42,12 +42,12 @@ public ResponseImpl(JsonObject data,
this.metadata = Collections.unmodifiableMap(headers != null ? headers : Collections.emptyMap());
}
- public ResponseImpl(JsonObject data, List errors, Map> headers,
+ public ResponseImpl(ObjectNode data, List errors, Map> headers,
Integer statusCode, String statusMessage) {
this(data, errors, null, headers, statusCode, statusMessage);
}
- public ResponseImpl(JsonObject data, List errors, JsonObject extensions,
+ public ResponseImpl(ObjectNode data, List errors, ObjectNode extensions,
Map> headers,
Integer statusCode, String statusMessage) {
this.data = data;
@@ -68,53 +68,53 @@ public ResponseImpl(JsonObject data, List errors, JsonObject exten
@Override
public T getObject(Class dataType, String rootField) {
- if (data == null || data.equals(JsonValue.NULL) || data.keySet().isEmpty()) {
+ if (data == null || data.isNull() || data.isEmpty()) {
throw SmallRyeGraphQLClientMessages.msg.noDataInResponse();
}
- JsonValue value = data.get(rootField);
+ JsonNode value = data.get(rootField);
if (value == null) {
// field is missing in the response completely
- throw SmallRyeGraphQLClientMessages.msg.fieldNotFoundInResponse(rootField, data.keySet());
+ throw SmallRyeGraphQLClientMessages.msg.fieldNotFoundInResponse(rootField, fieldNames(data));
}
- if (value.getValueType().equals(JsonValue.ValueType.NULL)) {
+ if (value.isNull()) {
// field is present in the response, but is null
return null;
}
- if (value.getValueType().equals(JsonValue.ValueType.OBJECT)) {
- return (T) JsonReader.readJson(rootField, TypeInfo.of(dataType), value.asJsonObject(), null);
- } else if (value.getValueType().equals(JsonValue.ValueType.ARRAY)) {
+ if (value.isObject()) {
+ return (T) JsonReader.readJson(rootField, TypeInfo.of(dataType), value, null);
+ } else if (value.isArray()) {
throw SmallRyeGraphQLClientMessages.msg.responseContainsArray(rootField);
} else {
Object scalarValue = getScalarValue(value);
if (scalarValue != null) {
return (T) scalarValue;
}
- throw SmallRyeGraphQLClientMessages.msg.unexpectedValueInResponse(rootField, value.getValueType().toString());
+ throw SmallRyeGraphQLClientMessages.msg.unexpectedValueInResponse(rootField, value.getNodeType().toString());
}
}
@Override
public List getList(Class dataType, String rootField) {
- if (data == null || data.equals(JsonValue.NULL) || data.keySet().isEmpty()) {
+ if (data == null || data.isNull() || data.isEmpty()) {
throw SmallRyeGraphQLClientMessages.msg.noDataInResponse();
}
- JsonValue item = data.get(rootField);
+ JsonNode item = data.get(rootField);
if (item == null) {
- throw SmallRyeGraphQLClientMessages.msg.fieldNotFoundInResponse(rootField, data.keySet());
+ throw SmallRyeGraphQLClientMessages.msg.fieldNotFoundInResponse(rootField, fieldNames(data));
}
- if (item.getValueType().equals(JsonValue.ValueType.NULL)) {
+ if (item.isNull()) {
// field is present in the response, but is null
return null;
}
- if (item instanceof JsonObject) {
+ if (item.isObject()) {
throw SmallRyeGraphQLClientMessages.msg.responseContainsSingleObject(rootField);
}
- if (item instanceof JsonArray) {
+ if (item.isArray()) {
List result = new ArrayList<>();
- JsonArray jsonArray = (JsonArray) item;
+ ArrayNode jsonArray = (ArrayNode) item;
TypeInfo type = TypeInfo.of(dataType);
jsonArray.forEach(o -> {
- if (o.getValueType().equals(JsonValue.ValueType.OBJECT)) {
+ if (o.isObject()) {
result.add((T) JsonReader.readJson(rootField, type, o, null));
} else {
result.add((T) getScalarValue(o));
@@ -122,26 +122,34 @@ public List getList(Class dataType, String rootField) {
});
return result;
}
- throw SmallRyeGraphQLClientMessages.msg.unexpectedValueInResponse(rootField, item.getValueType().toString());
+ throw SmallRyeGraphQLClientMessages.msg.unexpectedValueInResponse(rootField, item.getNodeType().toString());
}
- private Object getScalarValue(JsonValue value) {
- switch (value.getValueType()) {
+ private Object getScalarValue(JsonNode value) {
+ switch (value.getNodeType()) {
case NUMBER:
- return ((JsonNumber) value).longValue();
+ return value.longValue();
case STRING:
- return ((JsonString) value).getString();
- case TRUE:
- return true;
- case FALSE:
- return false;
+ return value.asText();
+ case BOOLEAN:
+ return value.booleanValue();
default:
return null;
}
}
+ /**
+ * Helper to collect field names from an ObjectNode into a Set-like structure
+ * for error reporting.
+ */
+ private static Set fieldNames(ObjectNode node) {
+ Set names = new LinkedHashSet<>();
+ node.fieldNames().forEachRemaining(names::add);
+ return names;
+ }
+
@Override
- public JsonObject getData() {
+ public ObjectNode getData() {
return data;
}
@@ -151,7 +159,7 @@ public List getErrors() {
}
@Override
- public JsonObject getExtensions() {
+ public ObjectNode getExtensions() {
return extensions;
}
diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java
index 6b1504c7c..e4dd866a8 100644
--- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java
+++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java
@@ -1,30 +1,25 @@
package io.smallrye.graphql.client.impl;
-import static io.smallrye.graphql.client.impl.JsonProviderHolder.JSON_PROVIDER;
-
-import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import jakarta.json.JsonArray;
-import jakarta.json.JsonNumber;
-import jakarta.json.JsonObject;
-import jakarta.json.JsonReader;
-import jakarta.json.JsonReaderFactory;
-import jakarta.json.JsonString;
-import jakarta.json.JsonValue;
-
import org.jboss.logging.Logger;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import io.smallrye.graphql.client.GraphQLError;
import io.smallrye.graphql.client.InvalidResponseException;
public class ResponseReader {
private static final Logger LOG = Logger.getLogger(ResponseReader.class.getName());
- private static final JsonReaderFactory jsonReaderFactory = JSON_PROVIDER.createReaderFactory(null);
+ private static final ObjectMapper MAPPER = RequestImpl.MAPPER;
/**
* Parse a GraphQL response from the input string.
@@ -33,21 +28,20 @@ public class ResponseReader {
* at least one of the keys 'data', 'extensions' and 'errors', but NO OTHER key.
* (see https://spec.graphql.org/draft/#sec-Response-Format)
*/
- public static JsonObject parseGraphQLResponse(String input) {
+ public static ObjectNode parseGraphQLResponse(String input) {
return parseGraphQLResponse(input, false);
}
- public static JsonObject parseGraphQLResponse(String input, Boolean allowUnexpectedResponseFields) {
+ public static ObjectNode parseGraphQLResponse(String input, Boolean allowUnexpectedResponseFields) {
if (input == null) {
return null;
}
- try (JsonReader jsonReader = jsonReaderFactory.createReader(new StringReader(input))) {
- JsonObject jsonResponse;
- try {
- jsonResponse = jsonReader.readObject();
- } catch (Exception e) {
+ try {
+ JsonNode parsed = MAPPER.readTree(input);
+ if (!parsed.isObject()) {
return null;
}
+ ObjectNode jsonResponse = (ObjectNode) parsed;
// validate that this is what we consider a GraphQL response - else return null
if (jsonResponse.size() >= 1) {
@@ -56,12 +50,16 @@ public static JsonObject parseGraphQLResponse(String input, Boolean allowUnexpec
} else {
return null;
}
+ } catch (JsonProcessingException e) {
+ return null;
}
}
- private static JsonObject checkExpectedResponseFields(JsonObject jsonResponse,
+ private static ObjectNode checkExpectedResponseFields(ObjectNode jsonResponse,
Boolean allowUnexpectedResponseFields) {
- for (String key : jsonResponse.keySet()) {
+ var fieldNames = jsonResponse.fieldNames();
+ while (fieldNames.hasNext()) {
+ String key = fieldNames.next();
if (!key.equalsIgnoreCase("data")
&& !key.equalsIgnoreCase("errors")
&& !key.equalsIgnoreCase("extensions")) {
@@ -75,40 +73,41 @@ private static JsonObject checkExpectedResponseFields(JsonObject jsonResponse,
public static ResponseImpl readFrom(String input, Map> headers, Integer statusCode,
String statusMessage, Boolean allowUnexpectedResponseFields) {
- JsonObject jsonResponse = parseGraphQLResponse(input, allowUnexpectedResponseFields);
+ ObjectNode jsonResponse = parseGraphQLResponse(input, allowUnexpectedResponseFields);
if (jsonResponse == null) {
throw new InvalidResponseException(
"Unexpected response. Code=" + statusCode + ", message=\"" + statusMessage + "\", " +
"body=\"" + input + "\"",
null, headers);
}
- JsonObject data = null;
- if (jsonResponse.containsKey("data")) {
- if (!jsonResponse.isNull("data")) {
- data = jsonResponse.getJsonObject("data");
+ ObjectNode data = null;
+ if (jsonResponse.has("data")) {
+ JsonNode dataNode = jsonResponse.get("data");
+ if (!dataNode.isNull()) {
+ data = (ObjectNode) dataNode;
} else {
SmallRyeGraphQLClientLogging.log.noDataInResponse();
}
}
List errors = null;
- if (jsonResponse.containsKey("errors")) {
+ if (jsonResponse.has("errors")) {
errors = new ArrayList<>();
- for (JsonValue error : jsonResponse.getJsonArray("errors")) {
+ for (JsonNode error : jsonResponse.get("errors")) {
errors.add(readError(error));
}
}
- boolean containsKeyExtension = jsonResponse.containsKey("extensions");
+ boolean containsKeyExtension = jsonResponse.has("extensions");
- if (containsKeyExtension && !jsonResponse.isNull("extensions")
- && !jsonResponse.get("extensions").getValueType().equals(JsonValue.ValueType.OBJECT)) {
+ if (containsKeyExtension && !jsonResponse.get("extensions").isNull()
+ && !jsonResponse.get("extensions").isObject()) {
LOG.warn("Unexpected value of 'extensions' in response: " + jsonResponse.get("extensions"));
}
- JsonObject extensions = null;
- if (containsKeyExtension && jsonResponse.get("extensions").getValueType().equals(JsonValue.ValueType.OBJECT)) {
- extensions = jsonResponse.getJsonObject("extensions");
+ ObjectNode extensions = null;
+ if (containsKeyExtension && jsonResponse.get("extensions").isObject()) {
+ extensions = (ObjectNode) jsonResponse.get("extensions");
}
return new ResponseImpl(data, errors, extensions, headers, statusCode, statusMessage);
@@ -123,31 +122,31 @@ public static ResponseImpl readFrom(String input, Map> head
return readFrom(input, headers, statusCode, statusMessage, false);
}
- public static GraphQLError readError(JsonValue errorJson) {
- JsonObject errorObject = errorJson.asJsonObject();
+ public static GraphQLError readError(JsonNode errorJson) {
+ ObjectNode errorObject = (ObjectNode) errorJson;
GraphQLErrorImpl decodedError = new GraphQLErrorImpl();
try {
- JsonValue message = errorObject.get("message");
- if (message instanceof JsonString) {
- decodedError.setMessage(errorObject.getString("message"));
+ JsonNode message = errorObject.get("message");
+ if (message != null && message.isTextual()) {
+ decodedError.setMessage(message.asText());
}
} catch (RuntimeException e) {
LOG.warn(e);
}
try {
- if (errorObject.containsKey("locations")
- && errorObject.get("locations").getValueType().equals(JsonValue.ValueType.ARRAY)) {
- JsonArray locations = errorObject.getJsonArray("locations");
+ if (errorObject.has("locations")
+ && errorObject.get("locations").isArray()) {
+ ArrayNode locations = (ArrayNode) errorObject.get("locations");
List