diff --git a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java index e74817c8e..63cdb28f8 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java @@ -302,6 +302,12 @@ private Object correctObjectClass(Object argumentValue, Field field, DataFetchin if (Map.class.isAssignableFrom(argumentValue.getClass())) { return correctComplexObjectFromMap((Map) argumentValue, field, dfe); } else if (receivedClassName.equals(String.class.getName())) { + // Edge case for ObjectId: If the field is of type org.bson.types.ObjectId, return the argument value. + // We need to handle ObjectId separately to avoid JSON-B calling its no-arg constructor, which would + // generate a new, random ID. By returning the argument value as is, we preserve the original ObjectId. + if (field.getReference().getClassName().equals("org.bson.types.ObjectId")) { + return argumentValue; + } // We got a String, but not expecting one. Lets bind to Pojo with JsonB // This happens with @DefaultValue and Transformable (Passthrough) Scalars return correctComplexObjectFromJsonString(argumentValue.toString(), field); diff --git a/server/integration-tests/pom.xml b/server/integration-tests/pom.xml index 615ff325d..ed3fd51f4 100644 --- a/server/integration-tests/pom.xml +++ b/server/integration-tests/pom.xml @@ -196,6 +196,11 @@ ${version.smallrye-stork} test + + org.mongodb + bson + test + org.jboss.shrinkwrap.resolver shrinkwrap-resolver-api-maven diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/ObjectIdAdapter.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/ObjectIdAdapter.java new file mode 100644 index 000000000..25569bd41 --- /dev/null +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/ObjectIdAdapter.java @@ -0,0 +1,17 @@ +package io.smallrye.graphql.tests.objectid; + +import org.bson.types.ObjectId; + +import io.smallrye.graphql.api.Adapter; + +public class ObjectIdAdapter implements Adapter { + @Override + public ObjectId from(String o) { + return new ObjectId(o); + } + + @Override + public String to(ObjectId a) throws Exception { + return a.toHexString(); + } +} diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/ObjectIdTest.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/ObjectIdTest.java new file mode 100644 index 000000000..913d85728 --- /dev/null +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/ObjectIdTest.java @@ -0,0 +1,42 @@ +package io.smallrye.graphql.tests.objectid; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URL; + +import org.bson.types.ObjectId; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; +import org.junit.runner.RunWith; + +import io.smallrye.graphql.tests.GraphQLAssured; + +@RunWith(Arquillian.class) +@RunAsClient +public class ObjectIdTest { + + @Deployment + public static WebArchive deployment() { + return ShrinkWrap.create(WebArchive.class, "objectId-test.war") + .addClasses(SomeApi.class, ObjectIdAdapter.class); + } + + @ArquillianResource + URL testingURL; + + @Test + public void queryWithObjectIdArgumentTest() { + final String id = ObjectId.get().toHexString(); + System.err.println(id); + GraphQLAssured graphQLAssured = new GraphQLAssured(testingURL); + + String response = graphQLAssured + .post("{ returnObjectId(id: \"" + id + "\") }"); + assertThat(response).contains("{\"data\":{\"returnObjectId\":\"" + id + "\"}}"); + } +} diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/SomeApi.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/SomeApi.java new file mode 100644 index 000000000..281ca8787 --- /dev/null +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/objectid/SomeApi.java @@ -0,0 +1,16 @@ +package io.smallrye.graphql.tests.objectid; + +import org.bson.types.ObjectId; +import org.eclipse.microprofile.graphql.GraphQLApi; +import org.eclipse.microprofile.graphql.Query; + +import io.smallrye.graphql.api.AdaptWith; + +@GraphQLApi +public class SomeApi { + @Query + public @AdaptWith(ObjectIdAdapter.class) ObjectId returnObjectId(@AdaptWith(ObjectIdAdapter.class) ObjectId id) { + return id; + } + +}