Description
Mutation using Object Literal fails with Field xxx has wrong value.
Could you please let us know if this error is because of unsupported feature, a bug, or something wrong..
We are using a custom scalar for mutation operation and running into issue..
Here are the details of the scalar data type, schema definition, and mutation (that works using stringified JSON but not using JS Object Literal)
Custom Scalar Definition
implicit val configurationDataType = ScalarType[JsValue]("configurationData",
description = Some("Either Raw JSON or Object literal value"),
coerceOutput = (value, _) ⇒ value.toString(),
coerceUserInput = {
case v: String ⇒ Right(Json.parse(v))
case v: Boolean ⇒ Right(JsBoolean(v))
case v: Int ⇒ Right(JsNumber(v))
case v: Long ⇒ Right(JsNumber(v))
case v: Float ⇒ Right(JsNumber(BigDecimal(v.toDouble)))
case v: Double ⇒ Right(JsNumber(v))
case v: BigInt ⇒ Right(JsNumber(BigDecimal(v)))
case v: BigDecimal ⇒ Right(JsNumber(v))
case v: JsValue ⇒ Right(v)
},
coerceInput = {
case ast.StringValue(jsonStr, _, _, , ) ⇒ {
Right(Json.parse(jsonStr))
}
case ast.ObjectValue(fields,,) ⇒ {
val configurartionPayLoad = fields.map(data => {
// Some code to convert input data to JSON String using NASHORN Java 8 approach
// Convert the update input argument data to JSON String
val result = nashorn.eval(s"var x = $jsString; JSON.stringify(x)", scriptContext)
val parsedJson = Json.parse(result.toString)
Json.obj("layers" -> parsedJson)
})
Right(configurartionPayLoad.head)
}
case _ ⇒ {
Left(JsonCoercionViolation)
}
})
// Schema Definition
case class UpdateEntityUnsetInput(configuration: Boolean)
case class UpdateEntitySetInput(configuration: String)
case class UpdateEntityInput(entityId: String,
set: Option[UpdateEntitySetInput],
unset: Option[UpdateEntityUnsetInput])
@singleton
class MyMutationSchemaDefinition {
import play.api.libs.json._
import sangria.macros.derive._
import sangria.marshalling.playJson._
implicit lazy val updateEntityUnSetInputFormat = Json.format[UpdateEntityUnsetInput]
implicit lazy val updateEntitySetInputFormat = Json.format[UpdateEntitySetInput]
implicit lazy val updateEntityFormat = Json.format[UpdateEntityInput]
implicit lazy val UpdateEntitySetInputType = InputObjectType[UpdateEntitySetInput]("UpdateEntitySetInput", List(
InputField("configuration", controllers.schema.utils.SchemaHelpers.configurationDataType)))
implicit lazy val UpdateEntityUnsetInputType = deriveInputObjectTypeUpdateEntityUnsetInput
implicit lazy val UpdateentityInputType = InputObjectType[UpdateentityInput]("UpdateentityInput", List(
InputField("entityId", IDType),
InputField("set", OptionInputType(UpdateEntitySetInputType)),
InputField("unset", OptionInputType(UpdateEntityUnsetInputType))))
val UpdateEntityInputArg = Argument("input", UpdateEntityInputType)
}
Mutation Using JS Object Literal Notation
mutation {
updateEntity(input: {entityId: “idValue",
set: {configuration: {layers: [{type: "LayerConfiguration",
key: {key1: "9155922381708984503", key2: “value2"}, key3: true},
{type: "LayerConfiguration",
key: {key1: “8768312111424122525", key2: "value2"}, key3: true}
]}}}) {
entity {
id
configuration {
data
}
}
}
}
Response / Output: Mutation Fails with the following error
{
"data": null,
"errors": [
{
"message": "Field 'input.set.configuration' has wrong value: Invalid value. (line 5, column 3):\n updateEntity(input: {entityId: \”idValue", \n ^\n (line 6, column 33):\n set: {configuration: {layers: [{type: "LayerConfiguration", \n ^",
"path": [
"updateEntity"
],
"locations": [
{
"line": 5,
"column": 3
},
{
"line": 6,
"column": 33
}
]
}
]
}
Mutation Using Escaped JSON String Notation
mutation {
updateEntity(input: {entityId: “idValue",
set: {configuration: "{"layers":[{"type":"LayerConfiguration","key":{"key1":"9155922381708984503","key2":"value2"},"key3":true}]}"}}) {
entity {
id
configuration {
data
}
}
}
}
Response / Output: Mutation is successful without errors